tests/test-linelog.py
author Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
Tue, 02 Jul 2019 12:59:58 -0400
changeset 42621 99ebde4fec99
parent 41365 876494fd967d
child 43076 2372284d9457
permissions -rw-r--r--
commit: improve the files field of changelog for merges Currently, the files list of merge commits repeats all the deletions (either actual deletions, or files that got renamed) that happened between base and p2 of the merge. If p2 is the main branch, the list can easily be much bigger than the change being merged. This results in various problems worth improving: - changelog is bigger than necessary - `hg log directory` lists many unrelated merge commits, and `hg log -v -r commit` frequently fills multiple screens worth of files - it possibly slows down adjustlinkrev, by forcing it to read more manifests, and that function can certainly be a bottleneck - the server side of pulls can waste a lot of time simply opening the filelogs for pointless files (the constant factors for opening even a tiny filelog is apparently pretty bad) So stop listing such files as described in the code. Impacted merge commits and their descendants get a different hash than they would have without this. This doesn't seem problematic, except for convert. The previous commit helped with that in the hg->hg case (but if you do svn->hg twice from scratch, hashes can still change). The rest of the description is numbers. I don't have much to report, because recreating the files list of existing repositories is not easy: - debugupgradeformat and bundle/unbundle don't recreate the list - export/import tends to choke quickly applying patches or on description that contain diffs, - merge commits from the convert extension don't have the right files list for reasons orthogonal to the current commit - replaying the merge with hg update/hg merge/hg revert --all/hg commit can end up failing in hg revert - I wasn't sure that using debugsetparents + debugrebuilddirstate would really build the right thing I measured commit time before and after this change, in a case with no files filtered out, several files filtered out (no difference) and 5k files filtered out (+1% time). Recreating the 100 more recent merges in a private repo, the concatenated uncompressed files lists goes from 1.12MB to 0.52MB. Excluding 3 merges that are not representative, then the size goes from 570k to 15k. I converted part of mozilla-central, and observed file list shrinking quite a bit too, starting at the very first merge, 733641d9feaf, going from 550 files to 10 files (although they have relatively few merges, so they probably wouldn't care). Differential Revision: https://phab.mercurial-scm.org/D6613
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
from __future__ import absolute_import, print_function
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
import difflib
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
import random
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
import unittest
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
from mercurial import linelog
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
38924
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
     9
vecratio = 3 # number of replacelines / number of replacelines_vec
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
maxlinenum = 0xffffff
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
maxb1 = 0xffffff
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
maxdeltaa = 10
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
maxdeltab = 10
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
def _genedits(seed, endrev):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
    lines = []
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    17
    random.seed(seed)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
    for rev in range(0, endrev):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
        n = len(lines)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
        a1 = random.randint(0, n)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
        a2 = random.randint(a1, min(n, a1 + maxdeltaa))
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
        b1 = random.randint(0, maxb1)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
        b2 = random.randint(b1, b1 + maxdeltab)
38924
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    24
        usevec = not bool(random.randint(0, vecratio))
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    25
        if usevec:
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    26
            blines = [(random.randint(0, rev), random.randint(0, maxlinenum))
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    27
                      for _ in range(b1, b2)]
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    28
        else:
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    29
            blines = [(rev, bidx) for bidx in range(b1, b2)]
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
        lines[a1:a2] = blines
38924
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
    31
        yield lines, rev, a1, a2, b1, b2, blines, usevec
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    32
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    33
class linelogtests(unittest.TestCase):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
    def testlinelogencodedecode(self):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    35
        program = [linelog._eof(0, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    36
                   linelog._jge(41, 42),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
                   linelog._jump(0, 43),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
                   linelog._eof(0, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    39
                   linelog._jl(44, 45),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    40
                   linelog._line(46, 47),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    41
                   ]
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
        ll = linelog.linelog(program, maxrev=100)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
        enc = ll.encode()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    44
        # round-trips okay
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
        self.assertEqual(linelog.linelog.fromdata(enc)._program, ll._program)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
        self.assertEqual(linelog.linelog.fromdata(enc), ll)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
        # This encoding matches the encoding used by hg-experimental's
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    48
        # linelog file, or is supposed to if it doesn't.
38809
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    49
        self.assertEqual(enc, (b'\x00\x00\x01\x90\x00\x00\x00\x06'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    50
                               b'\x00\x00\x00\xa4\x00\x00\x00*'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    51
                               b'\x00\x00\x00\x00\x00\x00\x00+'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    52
                               b'\x00\x00\x00\x00\x00\x00\x00\x00'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    53
                               b'\x00\x00\x00\xb1\x00\x00\x00-'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
    54
                               b'\x00\x00\x00\xba\x00\x00\x00/'))
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    56
    def testsimpleedits(self):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
        ll = linelog.linelog()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
        # Initial revision: add lines 0, 1, and 2
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
        ll.replacelines(1, 0, 0, 0, 3)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    60
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    61
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
                          (1, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
        # Replace line 1 with a new line
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
        ll.replacelines(2, 1, 2, 1, 2)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(2)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
                          (2, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    71
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
        # delete a line out of 2
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
        ll.replacelines(3, 1, 2, 0, 0)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(3)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    75
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
        # annotation of 1 is unchanged
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    80
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
                          (1, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    82
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    84
        ll.annotate(3) # set internal state to revision 3
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
        start = ll.getoffset(0)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    86
        end = ll.getoffset(1)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    87
        self.assertEqual(ll.getalllines(start, end), [
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
            (1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    89
            (2, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
            (1, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
        ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
        self.assertEqual(ll.getalllines(), [
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
            (1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    94
            (2, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
            (1, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    96
            (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    97
        ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
    99
    def testparseclinelogfile(self):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   100
        # This data is what the replacements in testsimpleedits
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
        # produce when fed to the original linelog.c implementation.
38809
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   102
        data = (b'\x00\x00\x00\x0c\x00\x00\x00\x0f'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   103
                b'\x00\x00\x00\x00\x00\x00\x00\x02'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   104
                b'\x00\x00\x00\x05\x00\x00\x00\x06'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   105
                b'\x00\x00\x00\x06\x00\x00\x00\x00'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   106
                b'\x00\x00\x00\x00\x00\x00\x00\x07'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   107
                b'\x00\x00\x00\x06\x00\x00\x00\x02'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   108
                b'\x00\x00\x00\x00\x00\x00\x00\x00'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   109
                b'\x00\x00\x00\t\x00\x00\x00\t'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   110
                b'\x00\x00\x00\x00\x00\x00\x00\x0c'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   111
                b'\x00\x00\x00\x08\x00\x00\x00\x05'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   112
                b'\x00\x00\x00\x06\x00\x00\x00\x01'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   113
                b'\x00\x00\x00\x00\x00\x00\x00\x05'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   114
                b'\x00\x00\x00\x0c\x00\x00\x00\x05'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   115
                b'\x00\x00\x00\n\x00\x00\x00\x01'
57af5ee15b35 linelog: port to Python 3
Augie Fackler <augie@google.com>
parents: 38795
diff changeset
   116
                b'\x00\x00\x00\x00\x00\x00\x00\t')
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
        llc = linelog.linelog.fromdata(data)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
        self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(1)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   119
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
                          (1, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   122
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   123
        self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(2)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   125
                          (2, 1),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   126
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   127
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   128
        self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(3)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
                         [(1, 0),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
                          (1, 2),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
                         ])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
        # Check we emit the same bytecode.
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   133
        ll = linelog.linelog()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
        # Initial revision: add lines 0, 1, and 2
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
        ll.replacelines(1, 0, 0, 0, 3)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   136
        # Replace line 1 with a new line
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
        ll.replacelines(2, 1, 2, 1, 2)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
        # delete a line out of 2
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   139
        ll.replacelines(3, 1, 2, 0, 0)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
        diff = '\n   ' + '\n   '.join(difflib.unified_diff(
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
            ll.debugstr().splitlines(), llc.debugstr().splitlines(),
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
            'python', 'c', lineterm=''))
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
        self.assertEqual(ll._program, llc._program, 'Program mismatch: ' + diff)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
        # Done as a secondary step so we get a better result if the
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
        # program is where the mismatch is.
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   146
        self.assertEqual(ll, llc)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   147
        self.assertEqual(ll.encode(), data)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   148
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   149
    def testanothersimplecase(self):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
        ll = linelog.linelog()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
        ll.replacelines(3, 0, 0, 0, 2)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
        ll.replacelines(4, 0, 2, 0, 0)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   153
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(4)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
                         [])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   155
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(3)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
                         [(3, 0), (3, 1)])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   157
        # rev 2 is empty because contents were only ever introduced in rev 3
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   158
        self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(2)],
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   159
                         [])
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   160
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   161
    def testrandomedits(self):
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
        # Inspired by original linelog tests.
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   163
        seed = random.random()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
        numrevs = 2000
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   165
        ll = linelog.linelog()
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
        # Populate linelog
38924
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   167
        for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   168
                seed, numrevs):
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   169
            if usevec:
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   170
                ll.replacelines_vec(rev, a1, a2, blines)
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   171
            else:
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   172
                ll.replacelines(rev, a1, a2, b1, b2)
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
            ar = ll.annotate(rev)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
            self.assertEqual(ll.annotateresult, lines)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
        # Verify we can get back these states by annotating each rev
38924
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   176
        for lines, rev, a1, a2, b1, b2, blines, usevec in _genedits(
6fed8b323651 linelog: add replacelines_vec for fastannotate
Augie Fackler <augie@google.com>
parents: 38809
diff changeset
   177
                seed, numrevs):
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
            ar = ll.annotate(rev)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
            self.assertEqual([(l.rev, l.linenum) for l in ar], lines)
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
38935
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   181
    def testinfinitebadprogram(self):
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   182
        ll = linelog.linelog.fromdata(
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   183
            b'\x00\x00\x00\x00\x00\x00\x00\x02'  # header
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   184
            b'\x00\x00\x00\x00\x00\x00\x00\x01'  # JUMP to self
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   185
        )
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   186
        with self.assertRaises(linelog.LineLogError):
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   187
            # should not be an infinite loop and raise
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   188
            ll.annotate(1)
27a54096c92e linelog: fix infinite loop vulnerability
Jun Wu <quark@fb.com>
parents: 38924
diff changeset
   189
38795
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   190
if __name__ == '__main__':
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   191
    import silenttestrunner
422d661056be linelog: add a Python implementation of the linelog datastructure
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
    silenttestrunner.main(__name__)