##// END OF EJS Templates
tests: finally fix up test-fuzz-targets.t...
tests: finally fix up test-fuzz-targets.t It's been failing on my workstation for a while, since I have a new enough LLVM that I had the fuzzer goo, but not so new that I actually had FuzzedDataProvider. This is a better solution all around in my opinion. I _believe_ this should let us run these tests on most systems, even those using GCC instead of clang. That said, my one attempt to test this on my macOS laptop failed miserably, and I don't feel like doing more work on this right now. Differential Revision: https://phab.mercurial-scm.org/D7566

File last commit:

r43346:2372284d default
r44267:19da643d default
Show More
test-linelog.py
197 lines | 6.9 KiB | text/x-python | PythonLexer
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 from __future__ import absolute_import, print_function
import difflib
import random
import unittest
from mercurial import linelog
Augie Fackler
formatting: blacken the codebase...
r43346 vecratio = 3 # number of replacelines / number of replacelines_vec
maxlinenum = 0xFFFFFF
maxb1 = 0xFFFFFF
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 maxdeltaa = 10
maxdeltab = 10
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 def _genedits(seed, endrev):
lines = []
random.seed(seed)
for rev in range(0, endrev):
n = len(lines)
a1 = random.randint(0, n)
a2 = random.randint(a1, min(n, a1 + maxdeltaa))
b1 = random.randint(0, maxb1)
b2 = random.randint(b1, b1 + maxdeltab)
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 usevec = not bool(random.randint(0, vecratio))
if usevec:
Augie Fackler
formatting: blacken the codebase...
r43346 blines = [
(random.randint(0, rev), random.randint(0, maxlinenum))
for _ in range(b1, b2)
]
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 else:
blines = [(rev, bidx) for bidx in range(b1, b2)]
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 lines[a1:a2] = blines
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 yield lines, rev, a1, a2, b1, b2, blines, usevec
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 class linelogtests(unittest.TestCase):
def testlinelogencodedecode(self):
Augie Fackler
formatting: blacken the codebase...
r43346 program = [
linelog._eof(0, 0),
linelog._jge(41, 42),
linelog._jump(0, 43),
linelog._eof(0, 0),
linelog._jl(44, 45),
linelog._line(46, 47),
]
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 ll = linelog.linelog(program, maxrev=100)
enc = ll.encode()
# round-trips okay
self.assertEqual(linelog.linelog.fromdata(enc)._program, ll._program)
self.assertEqual(linelog.linelog.fromdata(enc), ll)
# This encoding matches the encoding used by hg-experimental's
# linelog file, or is supposed to if it doesn't.
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
enc,
(
b'\x00\x00\x01\x90\x00\x00\x00\x06'
b'\x00\x00\x00\xa4\x00\x00\x00*'
b'\x00\x00\x00\x00\x00\x00\x00+'
b'\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\xb1\x00\x00\x00-'
b'\x00\x00\x00\xba\x00\x00\x00/'
),
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831
def testsimpleedits(self):
ll = linelog.linelog()
# Initial revision: add lines 0, 1, and 2
ll.replacelines(1, 0, 0, 0, 3)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
[(l.rev, l.linenum) for l in ll.annotate(1)],
[(1, 0), (1, 1), (1, 2),],
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 # Replace line 1 with a new line
ll.replacelines(2, 1, 2, 1, 2)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
[(l.rev, l.linenum) for l in ll.annotate(2)],
[(1, 0), (2, 1), (1, 2),],
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 # delete a line out of 2
ll.replacelines(3, 1, 2, 0, 0)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
[(l.rev, l.linenum) for l in ll.annotate(3)], [(1, 0), (1, 2),]
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 # annotation of 1 is unchanged
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
[(l.rev, l.linenum) for l in ll.annotate(1)],
[(1, 0), (1, 1), (1, 2),],
)
ll.annotate(3) # set internal state to revision 3
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 start = ll.getoffset(0)
end = ll.getoffset(1)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(ll.getalllines(start, end), [(1, 0), (2, 1), (1, 1),])
self.assertEqual(ll.getalllines(), [(1, 0), (2, 1), (1, 1), (1, 2),])
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831
def testparseclinelogfile(self):
# This data is what the replacements in testsimpleedits
# produce when fed to the original linelog.c implementation.
Augie Fackler
formatting: blacken the codebase...
r43346 data = (
b'\x00\x00\x00\x0c\x00\x00\x00\x0f'
b'\x00\x00\x00\x00\x00\x00\x00\x02'
b'\x00\x00\x00\x05\x00\x00\x00\x06'
b'\x00\x00\x00\x06\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x07'
b'\x00\x00\x00\x06\x00\x00\x00\x02'
b'\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\t\x00\x00\x00\t'
b'\x00\x00\x00\x00\x00\x00\x00\x0c'
b'\x00\x00\x00\x08\x00\x00\x00\x05'
b'\x00\x00\x00\x06\x00\x00\x00\x01'
b'\x00\x00\x00\x00\x00\x00\x00\x05'
b'\x00\x00\x00\x0c\x00\x00\x00\x05'
b'\x00\x00\x00\n\x00\x00\x00\x01'
b'\x00\x00\x00\x00\x00\x00\x00\t'
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 llc = linelog.linelog.fromdata(data)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual(
[(l.rev, l.linenum) for l in llc.annotate(1)],
[(1, 0), (1, 1), (1, 2),],
)
self.assertEqual(
[(l.rev, l.linenum) for l in llc.annotate(2)],
[(1, 0), (2, 1), (1, 2),],
)
self.assertEqual(
[(l.rev, l.linenum) for l in llc.annotate(3)], [(1, 0), (1, 2),]
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 # Check we emit the same bytecode.
ll = linelog.linelog()
# Initial revision: add lines 0, 1, and 2
ll.replacelines(1, 0, 0, 0, 3)
# Replace line 1 with a new line
ll.replacelines(2, 1, 2, 1, 2)
# delete a line out of 2
ll.replacelines(3, 1, 2, 0, 0)
Augie Fackler
formatting: blacken the codebase...
r43346 diff = '\n ' + '\n '.join(
difflib.unified_diff(
ll.debugstr().splitlines(),
llc.debugstr().splitlines(),
'python',
'c',
lineterm='',
)
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 self.assertEqual(ll._program, llc._program, 'Program mismatch: ' + diff)
# Done as a secondary step so we get a better result if the
# program is where the mismatch is.
self.assertEqual(ll, llc)
self.assertEqual(ll.encode(), data)
def testanothersimplecase(self):
ll = linelog.linelog()
ll.replacelines(3, 0, 0, 0, 2)
ll.replacelines(4, 0, 2, 0, 0)
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(4)], [])
self.assertEqual(
[(l.rev, l.linenum) for l in ll.annotate(3)], [(3, 0), (3, 1)]
)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 # rev 2 is empty because contents were only ever introduced in rev 3
Augie Fackler
formatting: blacken the codebase...
r43346 self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(2)], [])
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831
def testrandomedits(self):
# Inspired by original linelog tests.
seed = random.random()
numrevs = 2000
ll = linelog.linelog()
# Populate linelog
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
Augie Fackler
formatting: blacken the codebase...
r43346 seed, numrevs
):
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 if usevec:
ll.replacelines_vec(rev, a1, a2, blines)
else:
ll.replacelines(rev, a1, a2, b1, b2)
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 ar = ll.annotate(rev)
self.assertEqual(ll.annotateresult, lines)
# Verify we can get back these states by annotating each rev
Augie Fackler
linelog: add replacelines_vec for fastannotate...
r38960 for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
Augie Fackler
formatting: blacken the codebase...
r43346 seed, numrevs
):
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 ar = ll.annotate(rev)
self.assertEqual([(l.rev, l.linenum) for l in ar], lines)
Jun Wu
linelog: fix infinite loop vulnerability...
r38970 def testinfinitebadprogram(self):
ll = linelog.linelog.fromdata(
b'\x00\x00\x00\x00\x00\x00\x00\x02' # header
b'\x00\x00\x00\x00\x00\x00\x00\x01' # JUMP to self
)
with self.assertRaises(linelog.LineLogError):
# should not be an infinite loop and raise
ll.annotate(1)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 if __name__ == '__main__':
import silenttestrunner
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
linelog: add a Python implementation of the linelog datastructure...
r38831 silenttestrunner.main(__name__)