16 ) |
16 ) |
17 from .. import ( |
17 from .. import ( |
18 error, |
18 error, |
19 mdiff, |
19 mdiff, |
20 ) |
20 ) |
21 from ..interfaces import ( |
21 from ..interfaces import repository |
22 repository, |
22 from ..utils import storageutil |
23 ) |
23 |
24 from ..utils import ( |
|
25 storageutil, |
|
26 ) |
|
27 |
24 |
28 class basetestcase(unittest.TestCase): |
25 class basetestcase(unittest.TestCase): |
29 if not getattr(unittest.TestCase, r'assertRaisesRegex', False): |
26 if not getattr(unittest.TestCase, r'assertRaisesRegex', False): |
30 assertRaisesRegex = (# camelcase-required |
27 assertRaisesRegex = ( # camelcase-required |
31 unittest.TestCase.assertRaisesRegexp) |
28 unittest.TestCase.assertRaisesRegexp |
|
29 ) |
|
30 |
32 |
31 |
33 class ifileindextests(basetestcase): |
32 class ifileindextests(basetestcase): |
34 """Generic tests for the ifileindex interface. |
33 """Generic tests for the ifileindex interface. |
35 |
34 |
36 All file storage backends for index data should conform to the tests in this |
35 All file storage backends for index data should conform to the tests in this |
37 class. |
36 class. |
38 |
37 |
39 Use ``makeifileindextests()`` to create an instance of this type. |
38 Use ``makeifileindextests()`` to create an instance of this type. |
40 """ |
39 """ |
|
40 |
41 def testempty(self): |
41 def testempty(self): |
42 f = self._makefilefn() |
42 f = self._makefilefn() |
43 self.assertEqual(len(f), 0, 'new file store has 0 length by default') |
43 self.assertEqual(len(f), 0, 'new file store has 0 length by default') |
44 self.assertEqual(list(f), [], 'iter yields nothing by default') |
44 self.assertEqual(list(f), [], 'iter yields nothing by default') |
45 |
45 |
396 self.assertEqual(f.children(node2), []) |
396 self.assertEqual(f.children(node2), []) |
397 self.assertEqual(f.children(node3), [node4]) |
397 self.assertEqual(f.children(node3), [node4]) |
398 self.assertEqual(f.children(node4), []) |
398 self.assertEqual(f.children(node4), []) |
399 self.assertEqual(f.children(node5), []) |
399 self.assertEqual(f.children(node5), []) |
400 |
400 |
|
401 |
401 class ifiledatatests(basetestcase): |
402 class ifiledatatests(basetestcase): |
402 """Generic tests for the ifiledata interface. |
403 """Generic tests for the ifiledata interface. |
403 |
404 |
404 All file storage backends for data should conform to the tests in this |
405 All file storage backends for data should conform to the tests in this |
405 class. |
406 class. |
406 |
407 |
407 Use ``makeifiledatatests()`` to create an instance of this type. |
408 Use ``makeifiledatatests()`` to create an instance of this type. |
408 """ |
409 """ |
|
410 |
409 def testempty(self): |
411 def testempty(self): |
410 f = self._makefilefn() |
412 f = self._makefilefn() |
411 |
413 |
412 self.assertEqual(f.storageinfo(), {}) |
414 self.assertEqual(f.storageinfo(), {}) |
413 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True), |
415 self.assertEqual( |
414 {'revisionscount': 0, 'trackedsize': 0}) |
416 f.storageinfo(revisionscount=True, trackedsize=True), |
|
417 {'revisionscount': 0, 'trackedsize': 0}, |
|
418 ) |
415 |
419 |
416 self.assertEqual(f.size(nullrev), 0) |
420 self.assertEqual(f.size(nullrev), 0) |
417 |
421 |
418 for i in range(-5, 5): |
422 for i in range(-5, 5): |
419 if i == nullrev: |
423 if i == nullrev: |
464 f = self._makefilefn() |
468 f = self._makefilefn() |
465 with self._maketransactionfn() as tr: |
469 with self._maketransactionfn() as tr: |
466 node = f.add(fulltext, None, tr, 0, nullid, nullid) |
470 node = f.add(fulltext, None, tr, 0, nullid, nullid) |
467 |
471 |
468 self.assertEqual(f.storageinfo(), {}) |
472 self.assertEqual(f.storageinfo(), {}) |
469 self.assertEqual(f.storageinfo(revisionscount=True, trackedsize=True), |
473 self.assertEqual( |
470 {'revisionscount': 1, 'trackedsize': len(fulltext)}) |
474 f.storageinfo(revisionscount=True, trackedsize=True), |
|
475 {'revisionscount': 1, 'trackedsize': len(fulltext)}, |
|
476 ) |
471 |
477 |
472 self.assertEqual(f.size(0), len(fulltext)) |
478 self.assertEqual(f.size(0), len(fulltext)) |
473 |
479 |
474 with self.assertRaises(IndexError): |
480 with self.assertRaises(IndexError): |
475 f.size(1) |
481 f.size(1) |
601 self.assertEqual(rev.p2node, nullid) |
608 self.assertEqual(rev.p2node, nullid) |
602 self.assertIsNone(rev.linknode) |
609 self.assertIsNone(rev.linknode) |
603 self.assertEqual(rev.basenode, node0) |
610 self.assertEqual(rev.basenode, node0) |
604 self.assertIsNone(rev.baserevisionsize) |
611 self.assertIsNone(rev.baserevisionsize) |
605 self.assertIsNone(rev.revision) |
612 self.assertIsNone(rev.revision) |
606 self.assertEqual(rev.delta, |
613 self.assertEqual( |
607 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + |
614 rev.delta, |
608 fulltext1) |
615 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1, |
|
616 ) |
609 |
617 |
610 rev = next(gen) |
618 rev = next(gen) |
611 |
619 |
612 self.assertEqual(rev.node, node2) |
620 self.assertEqual(rev.node, node2) |
613 self.assertEqual(rev.p1node, node1) |
621 self.assertEqual(rev.p1node, node1) |
614 self.assertEqual(rev.p2node, nullid) |
622 self.assertEqual(rev.p2node, nullid) |
615 self.assertIsNone(rev.linknode) |
623 self.assertIsNone(rev.linknode) |
616 self.assertEqual(rev.basenode, node1) |
624 self.assertEqual(rev.basenode, node1) |
617 self.assertIsNone(rev.baserevisionsize) |
625 self.assertIsNone(rev.baserevisionsize) |
618 self.assertIsNone(rev.revision) |
626 self.assertIsNone(rev.revision) |
619 self.assertEqual(rev.delta, |
627 self.assertEqual( |
620 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + |
628 rev.delta, |
621 fulltext2) |
629 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2, |
|
630 ) |
622 |
631 |
623 with self.assertRaises(StopIteration): |
632 with self.assertRaises(StopIteration): |
624 next(gen) |
633 next(gen) |
625 |
634 |
626 # Request not in DAG order is reordered to be in DAG order. |
635 # Request not in DAG order is reordered to be in DAG order. |
644 self.assertEqual(rev.p2node, nullid) |
653 self.assertEqual(rev.p2node, nullid) |
645 self.assertIsNone(rev.linknode) |
654 self.assertIsNone(rev.linknode) |
646 self.assertEqual(rev.basenode, node0) |
655 self.assertEqual(rev.basenode, node0) |
647 self.assertIsNone(rev.baserevisionsize) |
656 self.assertIsNone(rev.baserevisionsize) |
648 self.assertIsNone(rev.revision) |
657 self.assertIsNone(rev.revision) |
649 self.assertEqual(rev.delta, |
658 self.assertEqual( |
650 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + |
659 rev.delta, |
651 fulltext1) |
660 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1, |
|
661 ) |
652 |
662 |
653 rev = next(gen) |
663 rev = next(gen) |
654 |
664 |
655 self.assertEqual(rev.node, node2) |
665 self.assertEqual(rev.node, node2) |
656 self.assertEqual(rev.p1node, node1) |
666 self.assertEqual(rev.p1node, node1) |
657 self.assertEqual(rev.p2node, nullid) |
667 self.assertEqual(rev.p2node, nullid) |
658 self.assertIsNone(rev.linknode) |
668 self.assertIsNone(rev.linknode) |
659 self.assertEqual(rev.basenode, node1) |
669 self.assertEqual(rev.basenode, node1) |
660 self.assertIsNone(rev.baserevisionsize) |
670 self.assertIsNone(rev.baserevisionsize) |
661 self.assertIsNone(rev.revision) |
671 self.assertIsNone(rev.revision) |
662 self.assertEqual(rev.delta, |
672 self.assertEqual( |
663 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + |
673 rev.delta, |
664 fulltext2) |
674 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2, |
|
675 ) |
665 |
676 |
666 with self.assertRaises(StopIteration): |
677 with self.assertRaises(StopIteration): |
667 next(gen) |
678 next(gen) |
668 |
679 |
669 # Unrecognized nodesorder value raises ProgrammingError. |
680 # Unrecognized nodesorder value raises ProgrammingError. |
670 with self.assertRaises(error.ProgrammingError): |
681 with self.assertRaises(error.ProgrammingError): |
671 list(f.emitrevisions([], nodesorder='bad')) |
682 list(f.emitrevisions([], nodesorder='bad')) |
672 |
683 |
673 # nodesorder=storage is recognized. But we can't test it thoroughly |
684 # nodesorder=storage is recognized. But we can't test it thoroughly |
674 # because behavior is storage-dependent. |
685 # because behavior is storage-dependent. |
675 res = list(f.emitrevisions([node2, node1, node0], |
686 res = list(f.emitrevisions([node2, node1, node0], nodesorder='storage')) |
676 nodesorder='storage')) |
|
677 self.assertEqual(len(res), 3) |
687 self.assertEqual(len(res), 3) |
678 self.assertEqual({o.node for o in res}, {node0, node1, node2}) |
688 self.assertEqual({o.node for o in res}, {node0, node1, node2}) |
679 |
689 |
680 # nodesorder=nodes forces the order. |
690 # nodesorder=nodes forces the order. |
681 gen = f.emitrevisions([node2, node0], nodesorder='nodes', |
691 gen = f.emitrevisions( |
682 revisiondata=True) |
692 [node2, node0], nodesorder='nodes', revisiondata=True |
|
693 ) |
683 |
694 |
684 rev = next(gen) |
695 rev = next(gen) |
685 self.assertEqual(rev.node, node2) |
696 self.assertEqual(rev.node, node2) |
686 self.assertEqual(rev.p1node, node1) |
697 self.assertEqual(rev.p1node, node1) |
687 self.assertEqual(rev.p2node, nullid) |
698 self.assertEqual(rev.p2node, nullid) |
717 self.assertEqual(rev.p1node, node1) |
728 self.assertEqual(rev.p1node, node1) |
718 self.assertEqual(rev.p2node, nullid) |
729 self.assertEqual(rev.p2node, nullid) |
719 self.assertEqual(rev.basenode, node1) |
730 self.assertEqual(rev.basenode, node1) |
720 self.assertIsNone(rev.baserevisionsize) |
731 self.assertIsNone(rev.baserevisionsize) |
721 self.assertIsNone(rev.revision) |
732 self.assertIsNone(rev.revision) |
722 self.assertEqual(rev.delta, |
733 self.assertEqual( |
723 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + |
734 rev.delta, |
724 fulltext2) |
735 b'\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x02' + fulltext2, |
|
736 ) |
725 |
737 |
726 with self.assertRaises(StopIteration): |
738 with self.assertRaises(StopIteration): |
727 next(gen) |
739 next(gen) |
728 |
740 |
729 # assumehaveparentrevisions=True allows delta against initial revision. |
741 # assumehaveparentrevisions=True allows delta against initial revision. |
730 gen = f.emitrevisions([node2, node1], |
742 gen = f.emitrevisions( |
731 revisiondata=True, assumehaveparentrevisions=True) |
743 [node2, node1], revisiondata=True, assumehaveparentrevisions=True |
|
744 ) |
732 |
745 |
733 rev = next(gen) |
746 rev = next(gen) |
734 self.assertEqual(rev.node, node1) |
747 self.assertEqual(rev.node, node1) |
735 self.assertEqual(rev.p1node, node0) |
748 self.assertEqual(rev.p1node, node0) |
736 self.assertEqual(rev.p2node, nullid) |
749 self.assertEqual(rev.p2node, nullid) |
737 self.assertEqual(rev.basenode, node0) |
750 self.assertEqual(rev.basenode, node0) |
738 self.assertIsNone(rev.baserevisionsize) |
751 self.assertIsNone(rev.baserevisionsize) |
739 self.assertIsNone(rev.revision) |
752 self.assertIsNone(rev.revision) |
740 self.assertEqual(rev.delta, |
753 self.assertEqual( |
741 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + |
754 rev.delta, |
742 fulltext1) |
755 b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x01' + fulltext1, |
|
756 ) |
743 |
757 |
744 # forceprevious=True forces a delta against the previous revision. |
758 # forceprevious=True forces a delta against the previous revision. |
745 # Special case for initial revision. |
759 # Special case for initial revision. |
746 gen = f.emitrevisions([node0], revisiondata=True, |
760 gen = f.emitrevisions( |
747 deltamode=repository.CG_DELTAMODE_PREV) |
761 [node0], revisiondata=True, deltamode=repository.CG_DELTAMODE_PREV |
|
762 ) |
748 |
763 |
749 rev = next(gen) |
764 rev = next(gen) |
750 self.assertEqual(rev.node, node0) |
765 self.assertEqual(rev.node, node0) |
751 self.assertEqual(rev.p1node, nullid) |
766 self.assertEqual(rev.p1node, nullid) |
752 self.assertEqual(rev.p2node, nullid) |
767 self.assertEqual(rev.p2node, nullid) |
753 self.assertEqual(rev.basenode, nullid) |
768 self.assertEqual(rev.basenode, nullid) |
754 self.assertIsNone(rev.baserevisionsize) |
769 self.assertIsNone(rev.baserevisionsize) |
755 self.assertIsNone(rev.revision) |
770 self.assertIsNone(rev.revision) |
756 self.assertEqual(rev.delta, |
771 self.assertEqual( |
757 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + |
772 rev.delta, |
758 fulltext0) |
773 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + fulltext0, |
|
774 ) |
759 |
775 |
760 with self.assertRaises(StopIteration): |
776 with self.assertRaises(StopIteration): |
761 next(gen) |
777 next(gen) |
762 |
778 |
763 gen = f.emitrevisions([node0, node2], revisiondata=True, |
779 gen = f.emitrevisions( |
764 deltamode=repository.CG_DELTAMODE_PREV) |
780 [node0, node2], |
|
781 revisiondata=True, |
|
782 deltamode=repository.CG_DELTAMODE_PREV, |
|
783 ) |
765 |
784 |
766 rev = next(gen) |
785 rev = next(gen) |
767 self.assertEqual(rev.node, node0) |
786 self.assertEqual(rev.node, node0) |
768 self.assertEqual(rev.p1node, nullid) |
787 self.assertEqual(rev.p1node, nullid) |
769 self.assertEqual(rev.p2node, nullid) |
788 self.assertEqual(rev.p2node, nullid) |
770 self.assertEqual(rev.basenode, nullid) |
789 self.assertEqual(rev.basenode, nullid) |
771 self.assertIsNone(rev.baserevisionsize) |
790 self.assertIsNone(rev.baserevisionsize) |
772 self.assertIsNone(rev.revision) |
791 self.assertIsNone(rev.revision) |
773 self.assertEqual(rev.delta, |
792 self.assertEqual( |
774 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + |
793 rev.delta, |
775 fulltext0) |
794 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + fulltext0, |
|
795 ) |
776 |
796 |
777 rev = next(gen) |
797 rev = next(gen) |
778 self.assertEqual(rev.node, node2) |
798 self.assertEqual(rev.node, node2) |
779 self.assertEqual(rev.p1node, node1) |
799 self.assertEqual(rev.p1node, node1) |
780 self.assertEqual(rev.p2node, nullid) |
800 self.assertEqual(rev.p2node, nullid) |
796 meta2 = { |
816 meta2 = { |
797 b'copy': b'source1', |
817 b'copy': b'source1', |
798 b'copyrev': b'b' * 40, |
818 b'copyrev': b'b' * 40, |
799 } |
819 } |
800 |
820 |
801 stored1 = b''.join([ |
821 stored1 = b''.join( |
802 b'\x01\ncopy: source0\n', |
822 [ |
803 b'copyrev: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\x01\n', |
823 b'\x01\ncopy: source0\n', |
804 fulltext1, |
824 b'copyrev: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\x01\n', |
805 ]) |
825 fulltext1, |
806 |
826 ] |
807 stored2 = b''.join([ |
827 ) |
808 b'\x01\ncopy: source1\n', |
828 |
809 b'copyrev: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n\x01\n', |
829 stored2 = b''.join( |
810 fulltext2, |
830 [ |
811 ]) |
831 b'\x01\ncopy: source1\n', |
|
832 b'copyrev: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n\x01\n', |
|
833 fulltext2, |
|
834 ] |
|
835 ) |
812 |
836 |
813 f = self._makefilefn() |
837 f = self._makefilefn() |
814 with self._maketransactionfn() as tr: |
838 with self._maketransactionfn() as tr: |
815 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
839 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
816 node1 = f.add(fulltext1, meta1, tr, 1, node0, nullid) |
840 node1 = f.add(fulltext1, meta1, tr, 1, node0, nullid) |
845 fulltext1 = b'\x01\nbar' |
869 fulltext1 = b'\x01\nbar' |
846 meta1 = { |
870 meta1 = { |
847 b'copy': b'source0', |
871 b'copy': b'source0', |
848 b'copyrev': b'b' * 40, |
872 b'copyrev': b'b' * 40, |
849 } |
873 } |
850 stored1 = b''.join([ |
874 stored1 = b''.join( |
851 b'\x01\ncopy: source0\n', |
875 [ |
852 b'copyrev: %s\n' % (b'b' * 40), |
876 b'\x01\ncopy: source0\n', |
853 b'\x01\n\x01\nbar', |
877 b'copyrev: %s\n' % (b'b' * 40), |
854 ]) |
878 b'\x01\n\x01\nbar', |
|
879 ] |
|
880 ) |
855 |
881 |
856 f = self._makefilefn() |
882 f = self._makefilefn() |
857 with self._maketransactionfn() as tr: |
883 with self._maketransactionfn() as tr: |
858 node0 = f.add(fulltext0, {}, tr, 0, nullid, nullid) |
884 node0 = f.add(fulltext0, {}, tr, 0, nullid, nullid) |
859 node1 = f.add(fulltext1, meta1, tr, 1, nullid, nullid) |
885 node1 = f.add(fulltext1, meta1, tr, 1, nullid, nullid) |
886 |
912 |
887 with self._maketransactionfn() as tr: |
913 with self._maketransactionfn() as tr: |
888 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
914 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
889 node1 = b'\xaa' * 20 |
915 node1 = b'\xaa' * 20 |
890 |
916 |
891 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, |
917 self._addrawrevisionfn( |
892 rawtext=fulltext1) |
918 f, tr, node1, node0, nullid, 1, rawtext=fulltext1 |
|
919 ) |
893 |
920 |
894 self.assertEqual(len(f), 2) |
921 self.assertEqual(len(f), 2) |
895 self.assertEqual(f.parents(node1), (node0, nullid)) |
922 self.assertEqual(f.parents(node1), (node0, nullid)) |
896 |
923 |
897 # revision() raises since it performs hash verification. |
924 # revision() raises since it performs hash verification. |
961 |
990 |
962 with self._maketransactionfn() as tr: |
991 with self._maketransactionfn() as tr: |
963 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
992 node0 = f.add(fulltext0, None, tr, 0, nullid, nullid) |
964 node1 = b'\xaa' * 20 |
993 node1 = b'\xaa' * 20 |
965 |
994 |
966 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, |
995 self._addrawrevisionfn( |
967 rawtext=fulltext1) |
996 f, tr, node1, node0, nullid, 1, rawtext=fulltext1 |
|
997 ) |
968 |
998 |
969 with self.assertRaises(error.StorageError): |
999 with self.assertRaises(error.StorageError): |
970 f.read(node1) |
1000 f.read(node1) |
971 |
1001 |
972 node2 = storageutil.hashrevisionsha1(fulltext2, node1, nullid) |
1002 node2 = storageutil.hashrevisionsha1(fulltext2, node1, nullid) |
973 |
1003 |
974 with self._maketransactionfn() as tr: |
1004 with self._maketransactionfn() as tr: |
975 delta = mdiff.textdiff(fulltext1, fulltext2) |
1005 delta = mdiff.textdiff(fulltext1, fulltext2) |
976 self._addrawrevisionfn(f, tr, node2, node1, nullid, |
1006 self._addrawrevisionfn( |
977 2, delta=(1, delta)) |
1007 f, tr, node2, node1, nullid, 2, delta=(1, delta) |
|
1008 ) |
978 |
1009 |
979 self.assertEqual(len(f), 3) |
1010 self.assertEqual(len(f), 3) |
980 |
1011 |
981 # Assuming a delta is stored, we shouldn't need to validate node1 in |
1012 # Assuming a delta is stored, we shouldn't need to validate node1 in |
982 # order to retrieve node2. |
1013 # order to retrieve node2. |
983 self.assertEqual(f.read(node2), fulltext2) |
1014 self.assertEqual(f.read(node2), fulltext2) |
984 |
1015 |
985 def testcensored(self): |
1016 def testcensored(self): |
986 f = self._makefilefn() |
1017 f = self._makefilefn() |
987 |
1018 |
988 stored1 = storageutil.packmeta({ |
1019 stored1 = storageutil.packmeta({b'censored': b'tombstone',}, b'') |
989 b'censored': b'tombstone', |
|
990 }, b'') |
|
991 |
1020 |
992 with self._maketransactionfn() as tr: |
1021 with self._maketransactionfn() as tr: |
993 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1022 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
994 |
1023 |
995 # The node value doesn't matter since we can't verify it. |
1024 # The node value doesn't matter since we can't verify it. |
996 node1 = b'\xbb' * 20 |
1025 node1 = b'\xbb' * 20 |
997 |
1026 |
998 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1, |
1027 self._addrawrevisionfn( |
999 censored=True) |
1028 f, tr, node1, node0, nullid, 1, stored1, censored=True |
|
1029 ) |
1000 |
1030 |
1001 self.assertTrue(f.iscensored(1)) |
1031 self.assertTrue(f.iscensored(1)) |
1002 |
1032 |
1003 with self.assertRaises(error.CensoredNodeError): |
1033 with self.assertRaises(error.CensoredNodeError): |
1004 f.revision(1) |
1034 f.revision(1) |
1013 # Like above, except we do the rawdata() request first to |
1043 # Like above, except we do the rawdata() request first to |
1014 # isolate revision caching behavior. |
1044 # isolate revision caching behavior. |
1015 |
1045 |
1016 f = self._makefilefn() |
1046 f = self._makefilefn() |
1017 |
1047 |
1018 stored1 = storageutil.packmeta({ |
1048 stored1 = storageutil.packmeta({b'censored': b'tombstone',}, b'') |
1019 b'censored': b'tombstone', |
|
1020 }, b'') |
|
1021 |
1049 |
1022 with self._maketransactionfn() as tr: |
1050 with self._maketransactionfn() as tr: |
1023 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1051 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1024 |
1052 |
1025 # The node value doesn't matter since we can't verify it. |
1053 # The node value doesn't matter since we can't verify it. |
1026 node1 = b'\xbb' * 20 |
1054 node1 = b'\xbb' * 20 |
1027 |
1055 |
1028 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1, |
1056 self._addrawrevisionfn( |
1029 censored=True) |
1057 f, tr, node1, node0, nullid, 1, stored1, censored=True |
|
1058 ) |
1030 |
1059 |
1031 with self.assertRaises(error.CensoredNodeError): |
1060 with self.assertRaises(error.CensoredNodeError): |
1032 f.rawdata(1) |
1061 f.rawdata(1) |
1033 |
1062 |
|
1063 |
1034 class ifilemutationtests(basetestcase): |
1064 class ifilemutationtests(basetestcase): |
1035 """Generic tests for the ifilemutation interface. |
1065 """Generic tests for the ifilemutation interface. |
1036 |
1066 |
1037 All file storage backends that support writing should conform to this |
1067 All file storage backends that support writing should conform to this |
1038 interface. |
1068 interface. |
1039 |
1069 |
1040 Use ``makeifilemutationtests()`` to create an instance of this type. |
1070 Use ``makeifilemutationtests()`` to create an instance of this type. |
1041 """ |
1071 """ |
|
1072 |
1042 def testaddnoop(self): |
1073 def testaddnoop(self): |
1043 f = self._makefilefn() |
1074 f = self._makefilefn() |
1044 with self._maketransactionfn() as tr: |
1075 with self._maketransactionfn() as tr: |
1045 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1076 node0 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1046 node1 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1077 node1 = f.add(b'foo', None, tr, 0, nullid, nullid) |
1147 |
1183 |
1148 def testdeltaagainstcensored(self): |
1184 def testdeltaagainstcensored(self): |
1149 # Attempt to apply a delta made against a censored revision. |
1185 # Attempt to apply a delta made against a censored revision. |
1150 f = self._makefilefn() |
1186 f = self._makefilefn() |
1151 |
1187 |
1152 stored1 = storageutil.packmeta({ |
1188 stored1 = storageutil.packmeta({b'censored': b'tombstone',}, b'') |
1153 b'censored': b'tombstone', |
|
1154 }, b'') |
|
1155 |
1189 |
1156 with self._maketransactionfn() as tr: |
1190 with self._maketransactionfn() as tr: |
1157 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid) |
1191 node0 = f.add(b'foo\n' * 30, None, tr, 0, nullid, nullid) |
1158 |
1192 |
1159 # The node value doesn't matter since we can't verify it. |
1193 # The node value doesn't matter since we can't verify it. |
1160 node1 = b'\xbb' * 20 |
1194 node1 = b'\xbb' * 20 |
1161 |
1195 |
1162 self._addrawrevisionfn(f, tr, node1, node0, nullid, 1, stored1, |
1196 self._addrawrevisionfn( |
1163 censored=True) |
1197 f, tr, node1, node0, nullid, 1, stored1, censored=True |
|
1198 ) |
1164 |
1199 |
1165 delta = mdiff.textdiff(b'bar\n' * 30, (b'bar\n' * 30) + b'baz\n') |
1200 delta = mdiff.textdiff(b'bar\n' * 30, (b'bar\n' * 30) + b'baz\n') |
1166 deltas = [(b'\xcc' * 20, node1, nullid, b'\x01' * 20, node1, delta, 0)] |
1201 deltas = [(b'\xcc' * 20, node1, nullid, b'\x01' * 20, node1, delta, 0)] |
1167 |
1202 |
1168 with self._maketransactionfn() as tr: |
1203 with self._maketransactionfn() as tr: |
1329 r'_maketransactionfn': maketransactionfn, |
1365 r'_maketransactionfn': maketransactionfn, |
1330 r'_addrawrevisionfn': addrawrevisionfn, |
1366 r'_addrawrevisionfn': addrawrevisionfn, |
1331 } |
1367 } |
1332 return type(r'ifileindextests', (ifileindextests,), d) |
1368 return type(r'ifileindextests', (ifileindextests,), d) |
1333 |
1369 |
|
1370 |
1334 def makeifiledatatests(makefilefn, maketransactionfn, addrawrevisionfn): |
1371 def makeifiledatatests(makefilefn, maketransactionfn, addrawrevisionfn): |
1335 d = { |
1372 d = { |
1336 r'_makefilefn': makefilefn, |
1373 r'_makefilefn': makefilefn, |
1337 r'_maketransactionfn': maketransactionfn, |
1374 r'_maketransactionfn': maketransactionfn, |
1338 r'_addrawrevisionfn': addrawrevisionfn, |
1375 r'_addrawrevisionfn': addrawrevisionfn, |
1339 } |
1376 } |
1340 return type(r'ifiledatatests', (ifiledatatests,), d) |
1377 return type(r'ifiledatatests', (ifiledatatests,), d) |
1341 |
1378 |
|
1379 |
1342 def makeifilemutationtests(makefilefn, maketransactionfn, addrawrevisionfn): |
1380 def makeifilemutationtests(makefilefn, maketransactionfn, addrawrevisionfn): |
1343 d = { |
1381 d = { |
1344 r'_makefilefn': makefilefn, |
1382 r'_makefilefn': makefilefn, |
1345 r'_maketransactionfn': maketransactionfn, |
1383 r'_maketransactionfn': maketransactionfn, |
1346 r'_addrawrevisionfn': addrawrevisionfn, |
1384 r'_addrawrevisionfn': addrawrevisionfn, |