tests/test-rust-revlog.py
branchstable
changeset 51438 05eba178da45
parent 51254 f94c10334bcb
--- a/tests/test-rust-revlog.py	Thu Feb 22 18:28:01 2024 +0100
+++ b/tests/test-rust-revlog.py	Fri Feb 23 15:10:44 2024 +0100
@@ -1,5 +1,8 @@
+import struct
 import unittest
 
+from mercurial.node import hex
+
 try:
     from mercurial import rustext
 
@@ -14,6 +17,8 @@
 
 from mercurial.testing import revlog as revlogtesting
 
+header = struct.unpack(">I", revlogtesting.data_non_inlined[:4])[0]
+
 
 @unittest.skipIf(
     rustext is None,
@@ -22,24 +27,16 @@
 class RustRevlogIndexTest(revlogtesting.RevlogBasedTestBase):
     def test_heads(self):
         idx = self.parseindex()
-        rustidx = revlog.MixedIndex(idx)
+        rustidx = revlog.Index(revlogtesting.data_non_inlined, header)
         self.assertEqual(rustidx.headrevs(), idx.headrevs())
 
-    def test_get_cindex(self):
-        # drop me once we no longer need the method for shortest node
-        idx = self.parseindex()
-        rustidx = revlog.MixedIndex(idx)
-        cidx = rustidx.get_cindex()
-        self.assertTrue(idx is cidx)
-
     def test_len(self):
         idx = self.parseindex()
-        rustidx = revlog.MixedIndex(idx)
+        rustidx = revlog.Index(revlogtesting.data_non_inlined, header)
         self.assertEqual(len(rustidx), len(idx))
 
     def test_ancestors(self):
-        idx = self.parseindex()
-        rustidx = revlog.MixedIndex(idx)
+        rustidx = revlog.Index(revlogtesting.data_non_inlined, header)
         lazy = LazyAncestors(rustidx, [3], 0, True)
         # we have two more references to the index:
         # - in its inner iterator for __contains__ and __bool__
@@ -51,7 +48,40 @@
         self.assertEqual(list(lazy), [3, 2, 1, 0])
 
         # let's check bool for an empty one
-        self.assertFalse(LazyAncestors(idx, [0], 0, False))
+        self.assertFalse(LazyAncestors(rustidx, [0], 0, False))
+
+
+@unittest.skipIf(
+    rustext is None,
+    "rustext module revlog relies on is not available",
+)
+class RustRevlogNodeTreeClassTest(revlogtesting.RustRevlogBasedTestBase):
+    def test_standalone_nodetree(self):
+        idx = self.parserustindex()
+        nt = revlog.NodeTree(idx)
+        for i in range(4):
+            nt.insert(i)
+
+        bin_nodes = [entry[7] for entry in idx]
+        hex_nodes = [hex(n) for n in bin_nodes]
+
+        for i, node in enumerate(hex_nodes):
+            self.assertEqual(nt.prefix_rev_lookup(node), i)
+            self.assertEqual(nt.prefix_rev_lookup(node[:5]), i)
+
+        # all 4 revisions in idx (standard data set) have different
+        # first nybbles in their Node IDs,
+        # hence `nt.shortest()` should return 1 for them, except when
+        # the leading nybble is 0 (ambiguity with NULL_NODE)
+        for i, (bin_node, hex_node) in enumerate(zip(bin_nodes, hex_nodes)):
+            shortest = nt.shortest(bin_node)
+            expected = 2 if hex_node[0] == ord('0') else 1
+            self.assertEqual(shortest, expected)
+            self.assertEqual(nt.prefix_rev_lookup(hex_node[:shortest]), i)
+
+        # test invalidation (generation poisoning) detection
+        del idx[3]
+        self.assertTrue(nt.is_invalidated())
 
 
 if __name__ == '__main__':