Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/testing/storage.py @ 40055:801ccd8e67c0
revlog: clear revision cache on hash verification failure
The revision cache is populated after raw revision fulltext is
retrieved but before hash verification. If hash verification
fails, the revision cache will be populated and subsequent
operations to retrieve the invalid fulltext may return the cached
fulltext instead of raising.
This commit changes hash verification so it will invalidate the
revision cache if the cached node fails hash verification. The
side-effect is that subsequent operations to request the revision
text - even the raw revision text - will always fail.
The new behavior is consistent and is definitely less wrong. There
is an open question of whether revision(raw=True) should validate
hashes. But I'm going to punt on this problem. We can always change
behavior later. And to be honest, I'm not sure we should expose
raw=True on the storage interface at all. Another day...
Differential Revision: https://phab.mercurial-scm.org/D4867
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 03 Oct 2018 10:57:35 -0700 |
parents | cdf61ab1f54c |
children | 324b4b10351e |
comparison
equal
deleted
inserted
replaced
40054:8c692a6b5ad1 | 40055:801ccd8e67c0 |
---|---|
879 | 879 |
880 # revision() raises since it performs hash verification. | 880 # revision() raises since it performs hash verification. |
881 with self.assertRaises(error.StorageError): | 881 with self.assertRaises(error.StorageError): |
882 f.revision(node1) | 882 f.revision(node1) |
883 | 883 |
884 # revision(raw=True) still verifies hashes. | 884 # raw=True still verifies because there are no special storage |
885 # TODO this is buggy because of cache interaction. | 885 # settings. |
886 self.assertEqual(f.revision(node1, raw=True), fulltext1) | 886 with self.assertRaises(error.StorageError): |
887 f.revision(node1, raw=True) | |
887 | 888 |
888 # read() behaves like revision(). | 889 # read() behaves like revision(). |
889 # TODO this is buggy because of cache interaction. | 890 with self.assertRaises(error.StorageError): |
890 f.read(node1) | 891 f.read(node1) |
891 | 892 |
892 # We can't test renamed() here because some backends may not require | 893 # We can't test renamed() here because some backends may not require |
893 # reading/validating the fulltext to return rename metadata. | 894 # reading/validating the fulltext to return rename metadata. |
894 | 895 |
895 def testbadnoderevisionraw(self): | 896 def testbadnoderevisionraw(self): |
929 rawtext=fulltext1) | 930 rawtext=fulltext1) |
930 | 931 |
931 with self.assertRaises(error.StorageError): | 932 with self.assertRaises(error.StorageError): |
932 f.read(node1) | 933 f.read(node1) |
933 | 934 |
934 # TODO this should raise error.StorageError. | 935 with self.assertRaises(error.StorageError): |
935 f.read(node1) | 936 f.read(node1) |
936 | 937 |
937 def testbadnodedelta(self): | 938 def testbadnodedelta(self): |
938 f = self._makefilefn() | 939 f = self._makefilefn() |
939 | 940 |
940 fulltext0 = b'foo\n' * 31 | 941 fulltext0 = b'foo\n' * 31 |
984 self.assertTrue(f.iscensored(1)) | 985 self.assertTrue(f.iscensored(1)) |
985 | 986 |
986 with self.assertRaises(error.CensoredNodeError): | 987 with self.assertRaises(error.CensoredNodeError): |
987 f.revision(1) | 988 f.revision(1) |
988 | 989 |
989 self.assertEqual(f.revision(1, raw=True), stored1) | 990 with self.assertRaises(error.CensoredNodeError): |
991 f.revision(1, raw=True) | |
990 | 992 |
991 with self.assertRaises(error.CensoredNodeError): | 993 with self.assertRaises(error.CensoredNodeError): |
992 f.read(1) | 994 f.read(1) |
993 | 995 |
994 def testcensoredrawrevision(self): | 996 def testcensoredrawrevision(self): |