##// END OF EJS Templates
py3: use pycompat.xrange instead of xrange...
Pulkit Goyal -
r40780:ba706e30 default
parent child Browse files
Show More
@@ -1,276 +1,276 b''
1 1 #!/usr/bin/env python
2 2 from __future__ import absolute_import
3 3
4 4 import hashlib
5 5 import os
6 6 import random
7 7 import shutil
8 8 import stat
9 9 import struct
10 10 import sys
11 11 import tempfile
12 12 import unittest
13 13
14 14 import silenttestrunner
15 15
16 16 from mercurial.node import nullid
17 17 from mercurial import (
18 18 pycompat,
19 19 ui as uimod,
20 20 )
21 21 # Load the local remotefilelog, not the system one
22 22 sys.path[0:0] = [os.path.join(os.path.dirname(__file__), '..')]
23 23 from hgext.remotefilelog import (
24 24 basepack,
25 25 historypack,
26 26 )
27 27
28 28 class histpacktests(unittest.TestCase):
29 29 def setUp(self):
30 30 self.tempdirs = []
31 31
32 32 def tearDown(self):
33 33 for d in self.tempdirs:
34 34 shutil.rmtree(d)
35 35
36 36 def makeTempDir(self):
37 37 tempdir = tempfile.mkdtemp()
38 38 self.tempdirs.append(tempdir)
39 39 return pycompat.fsencode(tempdir)
40 40
41 41 def getHash(self, content):
42 42 return hashlib.sha1(content).digest()
43 43
44 44 def getFakeHash(self):
45 45 return b''.join(pycompat.bytechr(random.randint(0, 255))
46 46 for _ in range(20))
47 47
48 48 def createPack(self, revisions=None):
49 49 """Creates and returns a historypack containing the specified revisions.
50 50
51 51 `revisions` is a list of tuples, where each tuple contains a filanem,
52 52 node, p1node, p2node, and linknode.
53 53 """
54 54 if revisions is None:
55 55 revisions = [("filename", self.getFakeHash(), nullid, nullid,
56 56 self.getFakeHash(), None)]
57 57
58 58 packdir = pycompat.fsencode(self.makeTempDir())
59 59 packer = historypack.mutablehistorypack(uimod.ui(), packdir,
60 60 version=2)
61 61
62 62 for filename, node, p1, p2, linknode, copyfrom in revisions:
63 63 packer.add(filename, node, p1, p2, linknode, copyfrom)
64 64
65 65 path = packer.close()
66 66 return historypack.historypack(path)
67 67
68 68 def testAddSingle(self):
69 69 """Test putting a single entry into a pack and reading it out.
70 70 """
71 71 filename = "foo"
72 72 node = self.getFakeHash()
73 73 p1 = self.getFakeHash()
74 74 p2 = self.getFakeHash()
75 75 linknode = self.getFakeHash()
76 76
77 77 revisions = [(filename, node, p1, p2, linknode, None)]
78 78 pack = self.createPack(revisions)
79 79
80 80 actual = pack.getancestors(filename, node)[node]
81 81 self.assertEquals(p1, actual[0])
82 82 self.assertEquals(p2, actual[1])
83 83 self.assertEquals(linknode, actual[2])
84 84
85 85 def testAddMultiple(self):
86 86 """Test putting multiple unrelated revisions into a pack and reading
87 87 them out.
88 88 """
89 89 revisions = []
90 90 for i in range(10):
91 91 filename = "foo-%s" % i
92 92 node = self.getFakeHash()
93 93 p1 = self.getFakeHash()
94 94 p2 = self.getFakeHash()
95 95 linknode = self.getFakeHash()
96 96 revisions.append((filename, node, p1, p2, linknode, None))
97 97
98 98 pack = self.createPack(revisions)
99 99
100 100 for filename, node, p1, p2, linknode, copyfrom in revisions:
101 101 actual = pack.getancestors(filename, node)[node]
102 102 self.assertEquals(p1, actual[0])
103 103 self.assertEquals(p2, actual[1])
104 104 self.assertEquals(linknode, actual[2])
105 105 self.assertEquals(copyfrom, actual[3])
106 106
107 107 def testAddAncestorChain(self):
108 108 """Test putting multiple revisions in into a pack and read the ancestor
109 109 chain.
110 110 """
111 111 revisions = []
112 112 filename = b"foo"
113 113 lastnode = nullid
114 114 for i in range(10):
115 115 node = self.getFakeHash()
116 116 revisions.append((filename, node, lastnode, nullid, nullid, None))
117 117 lastnode = node
118 118
119 119 # revisions must be added in topological order, newest first
120 120 revisions = list(reversed(revisions))
121 121 pack = self.createPack(revisions)
122 122
123 123 # Test that the chain has all the entries
124 124 ancestors = pack.getancestors(revisions[0][0], revisions[0][1])
125 125 for filename, node, p1, p2, linknode, copyfrom in revisions:
126 126 ap1, ap2, alinknode, acopyfrom = ancestors[node]
127 127 self.assertEquals(ap1, p1)
128 128 self.assertEquals(ap2, p2)
129 129 self.assertEquals(alinknode, linknode)
130 130 self.assertEquals(acopyfrom, copyfrom)
131 131
132 132 def testPackMany(self):
133 133 """Pack many related and unrelated ancestors.
134 134 """
135 135 # Build a random pack file
136 136 allentries = {}
137 137 ancestorcounts = {}
138 138 revisions = []
139 139 random.seed(0)
140 140 for i in range(100):
141 141 filename = b"filename-%d" % i
142 142 entries = []
143 143 p2 = nullid
144 144 linknode = nullid
145 145 for j in range(random.randint(1, 100)):
146 146 node = self.getFakeHash()
147 147 p1 = nullid
148 148 if len(entries) > 0:
149 149 p1 = entries[random.randint(0, len(entries) - 1)]
150 150 entries.append(node)
151 151 revisions.append((filename, node, p1, p2, linknode, None))
152 152 allentries[(filename, node)] = (p1, p2, linknode)
153 153 if p1 == nullid:
154 154 ancestorcounts[(filename, node)] = 1
155 155 else:
156 156 newcount = ancestorcounts[(filename, p1)] + 1
157 157 ancestorcounts[(filename, node)] = newcount
158 158
159 159 # Must add file entries in reverse topological order
160 160 revisions = list(reversed(revisions))
161 161 pack = self.createPack(revisions)
162 162
163 163 # Verify the pack contents
164 164 for (filename, node), (p1, p2, lastnode) in allentries.items():
165 165 ancestors = pack.getancestors(filename, node)
166 166 self.assertEquals(ancestorcounts[(filename, node)],
167 167 len(ancestors))
168 168 for anode, (ap1, ap2, alinknode, copyfrom) in ancestors.items():
169 169 ep1, ep2, elinknode = allentries[(filename, anode)]
170 170 self.assertEquals(ap1, ep1)
171 171 self.assertEquals(ap2, ep2)
172 172 self.assertEquals(alinknode, elinknode)
173 173 self.assertEquals(copyfrom, None)
174 174
175 175 def testGetNodeInfo(self):
176 176 revisions = []
177 177 filename = b"foo"
178 178 lastnode = nullid
179 179 for i in range(10):
180 180 node = self.getFakeHash()
181 181 revisions.append((filename, node, lastnode, nullid, nullid, None))
182 182 lastnode = node
183 183
184 184 pack = self.createPack(revisions)
185 185
186 186 # Test that getnodeinfo returns the expected results
187 187 for filename, node, p1, p2, linknode, copyfrom in revisions:
188 188 ap1, ap2, alinknode, acopyfrom = pack.getnodeinfo(filename, node)
189 189 self.assertEquals(ap1, p1)
190 190 self.assertEquals(ap2, p2)
191 191 self.assertEquals(alinknode, linknode)
192 192 self.assertEquals(acopyfrom, copyfrom)
193 193
194 194 def testGetMissing(self):
195 195 """Test the getmissing() api.
196 196 """
197 197 revisions = []
198 198 filename = b"foo"
199 199 for i in range(10):
200 200 node = self.getFakeHash()
201 201 p1 = self.getFakeHash()
202 202 p2 = self.getFakeHash()
203 203 linknode = self.getFakeHash()
204 204 revisions.append((filename, node, p1, p2, linknode, None))
205 205
206 206 pack = self.createPack(revisions)
207 207
208 208 missing = pack.getmissing([(filename, revisions[0][1])])
209 209 self.assertFalse(missing)
210 210
211 211 missing = pack.getmissing([(filename, revisions[0][1]),
212 212 (filename, revisions[1][1])])
213 213 self.assertFalse(missing)
214 214
215 215 fakenode = self.getFakeHash()
216 216 missing = pack.getmissing([(filename, revisions[0][1]),
217 217 (filename, fakenode)])
218 218 self.assertEquals(missing, [(filename, fakenode)])
219 219
220 220 # Test getmissing on a non-existant filename
221 221 missing = pack.getmissing([("bar", fakenode)])
222 222 self.assertEquals(missing, [("bar", fakenode)])
223 223
224 224 def testAddThrows(self):
225 225 pack = self.createPack()
226 226
227 227 try:
228 228 pack.add(b'filename', nullid, nullid, nullid, nullid, None)
229 229 self.assertTrue(False, "historypack.add should throw")
230 230 except RuntimeError:
231 231 pass
232 232
233 233 def testBadVersionThrows(self):
234 234 pack = self.createPack()
235 235 path = pack.path + '.histpack'
236 236 with open(path) as f:
237 237 raw = f.read()
238 238 raw = struct.pack('!B', 255) + raw[1:]
239 239 os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE)
240 240 with open(path, 'w+') as f:
241 241 f.write(raw)
242 242
243 243 try:
244 244 pack = historypack.historypack(pack.path)
245 245 self.assertTrue(False, "bad version number should have thrown")
246 246 except RuntimeError:
247 247 pass
248 248
249 249 def testLargePack(self):
250 250 """Test creating and reading from a large pack with over X entries.
251 251 This causes it to use a 2^16 fanout table instead."""
252 252 total = basepack.SMALLFANOUTCUTOFF + 1
253 253 revisions = []
254 for i in xrange(total):
254 for i in pycompat.xrange(total):
255 255 filename = b"foo-%d" % i
256 256 node = self.getFakeHash()
257 257 p1 = self.getFakeHash()
258 258 p2 = self.getFakeHash()
259 259 linknode = self.getFakeHash()
260 260 revisions.append((filename, node, p1, p2, linknode, None))
261 261
262 262 pack = self.createPack(revisions)
263 263 self.assertEquals(pack.params.fanoutprefix, basepack.LARGEFANOUTPREFIX)
264 264
265 265 for filename, node, p1, p2, linknode, copyfrom in revisions:
266 266 actual = pack.getancestors(filename, node)[node]
267 267 self.assertEquals(p1, actual[0])
268 268 self.assertEquals(p2, actual[1])
269 269 self.assertEquals(linknode, actual[2])
270 270 self.assertEquals(copyfrom, actual[3])
271 271 # TODO:
272 272 # histpack store:
273 273 # - repack two packs into one
274 274
275 275 if __name__ == '__main__':
276 276 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now