annotate tests/test-rust-revlog.py @ 52799:4e34e8fd46d4

rust-pyo3-revlog: nodemap based index methods They are rather straightforward, except for `_index_get_rev` that takes care of not initializing a nodetree on some conditions. In `_index_partialmatch`, we solve the todo that was in the `hg-cpython`, since we introduced the `py_node_for_rev` helper earlier. The new test method in `test-rust-revlog.py` provides comparison with the `hg-cpython` implementation of `InnerRevlog`.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 25 Dec 2024 16:16:22 +0100
parents 07740bd86fd9
children e5f89bd1a5ee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52796
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
1 import struct
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
2
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
3 from mercurial.node import (
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
4 bin as node_bin,
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
5 hex,
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
6 )
52799
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
7 from mercurial import error
52796
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
8
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
9 try:
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
10 from mercurial import rustext
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
11
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
12 rustext.__name__ # trigger immediate actual import
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
13 except ImportError:
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
14 rustext = None
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
15 else:
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
16 # this would fail already without appropriate ancestor.__package__
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
17 from mercurial.rustext.ancestor import LazyAncestors
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
18
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
19 from mercurial.testing import revlog as revlogtesting
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
20
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
21 header = struct.unpack(">I", revlogtesting.data_non_inlined[:4])[0]
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
22
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
23
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
24 class RustInnerRevlogTestMixin:
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
25 """Common tests for both Rust Python bindings."""
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
26
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
27 node_hex0 = b'd1f4bbb0befc13bd8cd39d0fcdd93b8c078c4a2f'
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
28 node0 = node_bin(node_hex0)
52799
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
29 bogus_node_hex = b'cafe' * 10
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
30 bogus_node = node_bin(bogus_node_hex)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
31
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
32 def test_index_nodemap(self):
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
33 idx = self.parserustindex()
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
34 self.assertTrue(idx.has_node(self.node0))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
35 self.assertFalse(idx.has_node(self.bogus_node))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
36
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
37 self.assertEqual(idx.get_rev(self.node0), 0)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
38 self.assertEqual(idx.get_rev(self.node0), 0)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
39
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
40 self.assertEqual(idx.rev(self.node0), 0)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
41 with self.assertRaises(error.RevlogError) as exc_info:
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
42 idx.rev(self.bogus_node)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
43 self.assertEqual(exc_info.exception.args, (None,))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
44
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
45 self.assertEqual(idx.partialmatch(self.node_hex0[:3]), self.node0)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
46 self.assertIsNone(idx.partialmatch(self.bogus_node_hex[:3]))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52796
diff changeset
47 self.assertEqual(idx.shortest(self.node0), 1)
52796
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
48
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
49
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
50 # Conditional skipping done by the base class
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
51 class RustInnerRevlogTest(
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
52 revlogtesting.RustRevlogBasedTestBase, RustInnerRevlogTestMixin
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
53 ):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
54 """For reference"""
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
55
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
56 def test_heads(self):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
57 idx = self.parserustindex()
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
58 self.assertEqual(idx.headrevs(), [3])
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
59
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
60 def test_len(self):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
61 idx = self.parserustindex()
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
62 self.assertEqual(len(idx), 4)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
63
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
64 def test_ancestors(self):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
65 rustidx = self.parserustindex()
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
66 lazy = LazyAncestors(rustidx, [3], 0, True)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
67 # we have two more references to the index:
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
68 # - in its inner iterator for __contains__ and __bool__
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
69 # - in the LazyAncestors instance itself (to spawn new iterators)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
70 self.assertTrue(2 in lazy)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
71 self.assertTrue(bool(lazy))
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
72 self.assertEqual(list(lazy), [3, 2, 1, 0])
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
73 # a second time to validate that we spawn new iterators
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
74 self.assertEqual(list(lazy), [3, 2, 1, 0])
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
75
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
76 # let's check bool for an empty one
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
77 self.assertFalse(LazyAncestors(rustidx, [0], 0, False))
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
78
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
79 def test_standalone_nodetree(self):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
80 idx = self.parserustindex()
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
81 nt = self.nodetree(idx)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
82 for i in range(4):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
83 nt.insert(i)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
84
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
85 bin_nodes = [entry[7] for entry in idx]
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
86 hex_nodes = [hex(n) for n in bin_nodes]
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
87
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
88 for i, node in enumerate(hex_nodes):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
89 self.assertEqual(nt.prefix_rev_lookup(node), i)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
90 self.assertEqual(nt.prefix_rev_lookup(node[:5]), i)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
91
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
92 # all 4 revisions in idx (standard data set) have different
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
93 # first nybbles in their Node IDs,
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
94 # hence `nt.shortest()` should return 1 for them, except when
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
95 # the leading nybble is 0 (ambiguity with NULL_NODE)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
96 for i, (bin_node, hex_node) in enumerate(zip(bin_nodes, hex_nodes)):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
97 shortest = nt.shortest(bin_node)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
98 expected = 2 if hex_node[0] == ord('0') else 1
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
99 self.assertEqual(shortest, expected)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
100 self.assertEqual(nt.prefix_rev_lookup(hex_node[:shortest]), i)
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
101
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
102 # test invalidation (generation poisoning) detection
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
103 del idx[3]
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
104 self.assertTrue(nt.is_invalidated())
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
105
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
106
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
107 # Conditional skipping done by the base class
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
108 class PyO3InnerRevlogTest(
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
109 revlogtesting.PyO3RevlogBasedTestBase, RustInnerRevlogTestMixin
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
110 ):
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
111 """Testing new PyO3 bindings, by comparison with rust-cpython bindings."""
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
112
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
113
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
114 if __name__ == '__main__':
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
115 import silenttestrunner
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
116
07740bd86fd9 rust-pyo3: reviving test-rust-revlog.py
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
117 silenttestrunner.main(__name__)