tests/test-rust-ancestor.py
changeset 41053 d9f439fcdb4c
parent 40968 74f41329bf55
child 41114 b31a41f24864
equal deleted inserted replaced
41052:4c25038c112c 41053:d9f439fcdb4c
     1 from __future__ import absolute_import
     1 from __future__ import absolute_import
       
     2 import sys
     2 import unittest
     3 import unittest
     3 
     4 
     4 try:
     5 try:
     5     from mercurial import rustext
     6     from mercurial import rustext
       
     7     rustext.__name__  # trigger immediate actual import
     6 except ImportError:
     8 except ImportError:
     7     rustext = None
     9     rustext = None
       
    10 else:
       
    11     # this would fail already without appropriate ancestor.__package__
       
    12     from mercurial.rustext.ancestor import AncestorsIterator
     8 
    13 
     9 try:
    14 try:
    10     from mercurial.cext import parsers as cparsers
    15     from mercurial.cext import parsers as cparsers
    11 except ImportError:
    16 except ImportError:
    12     cparsers = None
    17     cparsers = None
    13 
    18 
       
    19 # picked from test-parse-index2, copied rather than imported
       
    20 # so that it stays stable even if test-parse-index2 changes or disappears.
       
    21 data_non_inlined = (
       
    22     b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01D\x19'
       
    23     b'\x00\x07e\x12\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff'
       
    24     b'\xff\xff\xff\xff\xd1\xf4\xbb\xb0\xbe\xfc\x13\xbd\x8c\xd3\x9d'
       
    25     b'\x0f\xcd\xd9;\x8c\x07\x8cJ/\x00\x00\x00\x00\x00\x00\x00\x00\x00'
       
    26     b'\x00\x00\x00\x00\x00\x00\x01D\x19\x00\x00\x00\x00\x00\xdf\x00'
       
    27     b'\x00\x01q\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff'
       
    28     b'\xff\xff\xff\xc1\x12\xb9\x04\x96\xa4Z1t\x91\xdfsJ\x90\xf0\x9bh'
       
    29     b'\x07l&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
       
    30     b'\x00\x01D\xf8\x00\x00\x00\x00\x01\x1b\x00\x00\x01\xb8\x00\x00'
       
    31     b'\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\x02\n'
       
    32     b'\x0e\xc6&\xa1\x92\xae6\x0b\x02i\xfe-\xe5\xbao\x05\xd1\xe7\x00'
       
    33     b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01F'
       
    34     b'\x13\x00\x00\x00\x00\x01\xec\x00\x00\x03\x06\x00\x00\x00\x01'
       
    35     b'\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x12\xcb\xeby1'
       
    36     b'\xb6\r\x98B\xcb\x07\xbd`\x8f\x92\xd9\xc4\x84\xbdK\x00\x00\x00'
       
    37     b'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
       
    38     )
       
    39 
       
    40 
    14 @unittest.skipIf(rustext is None or cparsers is None,
    41 @unittest.skipIf(rustext is None or cparsers is None,
    15                  "rustext.ancestor or the C Extension parsers module "
    42                  "rustext or the C Extension parsers module "
    16                  "it relies on is not available")
    43                  "ancestor relies on is not available")
    17 class rustancestorstest(unittest.TestCase):
    44 class rustancestorstest(unittest.TestCase):
    18     """Test the correctness of binding to Rust code.
    45     """Test the correctness of binding to Rust code.
    19 
    46 
    20     This test is merely for the binding to Rust itself: extraction of
    47     This test is merely for the binding to Rust itself: extraction of
    21     Python variable, giving back the results etc.
    48     Python variable, giving back the results etc.
    25     good enough.
    52     good enough.
    26 
    53 
    27     Algorithmic correctness is asserted by the Rust unit tests.
    54     Algorithmic correctness is asserted by the Rust unit tests.
    28     """
    55     """
    29 
    56 
    30     def testmodule(self):
    57     def parseindex(self):
    31         self.assertTrue('DAG' in rustext.ancestor.__doc__)
    58         return cparsers.parse_index2(data_non_inlined, False)[0]
       
    59 
       
    60     def testiteratorrevlist(self):
       
    61         idx = self.parseindex()
       
    62         # checking test assumption about the index binary data:
       
    63         self.assertEqual({i: (r[5], r[6]) for i, r in enumerate(idx)},
       
    64                          {0: (-1, -1),
       
    65                           1: (0, -1),
       
    66                           2: (1, -1),
       
    67                           3: (2, -1)})
       
    68         ait = AncestorsIterator(idx, [3], 0, True)
       
    69         self.assertEqual([r for r in ait], [3, 2, 1, 0])
       
    70 
       
    71         ait = AncestorsIterator(idx, [3], 0, False)
       
    72         self.assertEqual([r for r in ait], [2, 1, 0])
       
    73 
       
    74     def testrefcount(self):
       
    75         idx = self.parseindex()
       
    76         start_count = sys.getrefcount(idx)
       
    77 
       
    78         # refcount increases upon iterator init...
       
    79         ait = AncestorsIterator(idx, [3], 0, True)
       
    80         self.assertEqual(sys.getrefcount(idx), start_count + 1)
       
    81         self.assertEqual(next(ait), 3)
       
    82 
       
    83         # and decreases once the iterator is removed
       
    84         del ait
       
    85         self.assertEqual(sys.getrefcount(idx), start_count)
       
    86 
       
    87         # and removing ref to the index after iterator init is no issue
       
    88         ait = AncestorsIterator(idx, [3], 0, True)
       
    89         del idx
       
    90         self.assertEqual([r for r in ait], [3, 2, 1, 0])
    32 
    91 
    33     def testgrapherror(self):
    92     def testgrapherror(self):
    34         self.assertTrue('GraphError' in dir(rustext))
    93         data = (data_non_inlined[:64 + 27] +
       
    94                 b'\xf2' +
       
    95                 data_non_inlined[64 + 28:])
       
    96         idx = cparsers.parse_index2(data, False)[0]
       
    97         with self.assertRaises(rustext.GraphError) as arc:
       
    98             AncestorsIterator(idx, [1], -1, False)
       
    99         exc = arc.exception
       
   100         self.assertIsInstance(exc, ValueError)
       
   101         # rust-cpython issues appropriate str instances for Python 2 and 3
       
   102         self.assertEqual(exc.args, ('ParentOutOfRange', 1))
    35 
   103 
    36 
   104 
    37 if __name__ == '__main__':
   105 if __name__ == '__main__':
    38     import silenttestrunner
   106     import silenttestrunner
    39     silenttestrunner.main(__name__)
   107     silenttestrunner.main(__name__)