/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_knit.py

  • Committer: Andrew Bennetts
  • Date: 2008-04-07 10:34:57 UTC
  • mfrom: (3344 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3349.
  • Revision ID: andrew.bennetts@canonical.com-20080407103457-ro4t95pd3imwt0zw
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
554
554
            "version option 0 1 .%s :" % (utf8_revision_id,)
555
555
            ])
556
556
        index = self.get_knit_index(transport, "filename", "r")
557
 
        self.assertEqual([utf8_revision_id],
 
557
        self.assertEqual((utf8_revision_id,),
558
558
            index.get_parents_with_ghosts("version"))
559
559
 
560
560
    def test_read_ignore_corrupted_lines(self):
588
588
        self.assertEqual("1", index._version_list_to_index(["version"]))
589
589
        self.assertEqual((None, 3, 4), index.get_position("version"))
590
590
        self.assertEqual(["options3"], index.get_options("version"))
591
 
        self.assertEqual(["parent", "other"],
 
591
        self.assertEqual(("parent", "other"),
592
592
            index.get_parents_with_ghosts("version"))
593
593
 
594
594
    def test_read_compressed_parents(self):
599
599
            "c option 0 1 1 0 :",
600
600
            ])
601
601
        index = self.get_knit_index(transport, "filename", "r")
602
 
        self.assertEqual(["a"], index.get_parents("b"))
603
 
        self.assertEqual(["b", "a"], index.get_parents("c"))
 
602
        self.assertEqual({"b":("a",), "c":("b", "a")},
 
603
            index.get_parent_map(["b", "c"]))
604
604
 
605
605
    def test_write_utf8_version_id(self):
606
606
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
628
628
            {}),
629
629
            transport.calls.pop(0))
630
630
 
631
 
    def test_get_graph(self):
632
 
        transport = MockTransport()
633
 
        index = self.get_knit_index(transport, "filename", "w", create=True)
634
 
        self.assertEqual([], index.get_graph())
635
 
 
636
 
        index.add_version("a", ["option"], (None, 0, 1), ["b"])
637
 
        self.assertEqual([("a", ["b"])], index.get_graph())
638
 
 
639
 
        index.add_version("c", ["option"], (None, 0, 1), ["d"])
640
 
        self.assertEqual([("a", ["b"]), ("c", ["d"])],
641
 
            sorted(index.get_graph()))
642
 
 
643
631
    def test_get_ancestry(self):
644
632
        transport = MockTransport([
645
633
            _KnitIndex.HEADER,
771
759
        self.assertEqual(1, index.num_versions())
772
760
        self.assertEqual((None, 0, 1), index.get_position("a"))
773
761
        self.assertEqual(["option"], index.get_options("a"))
774
 
        self.assertEqual(["b"], index.get_parents_with_ghosts("a"))
 
762
        self.assertEqual(("b",), index.get_parents_with_ghosts("a"))
775
763
 
776
764
        index.add_version("a", ["opt"], (None, 1, 2), ["c"])
777
765
        self.assertEqual(("append_bytes",
781
769
        self.assertEqual(1, index.num_versions())
782
770
        self.assertEqual((None, 1, 2), index.get_position("a"))
783
771
        self.assertEqual(["opt"], index.get_options("a"))
784
 
        self.assertEqual(["c"], index.get_parents_with_ghosts("a"))
 
772
        self.assertEqual(("c",), index.get_parents_with_ghosts("a"))
785
773
 
786
774
        index.add_version("b", ["option"], (None, 2, 3), ["a"])
787
775
        self.assertEqual(("append_bytes",
791
779
        self.assertEqual(2, index.num_versions())
792
780
        self.assertEqual((None, 2, 3), index.get_position("b"))
793
781
        self.assertEqual(["option"], index.get_options("b"))
794
 
        self.assertEqual(["a"], index.get_parents_with_ghosts("b"))
 
782
        self.assertEqual(("a",), index.get_parents_with_ghosts("b"))
795
783
 
796
784
    def test_add_versions(self):
797
785
        transport = MockTransport([
816
804
        self.assertEqual((None, 2, 3), index.get_position("b"))
817
805
        self.assertEqual(["opt"], index.get_options("a"))
818
806
        self.assertEqual(["option"], index.get_options("b"))
819
 
        self.assertEqual(["c"], index.get_parents_with_ghosts("a"))
820
 
        self.assertEqual(["a"], index.get_parents_with_ghosts("b"))
 
807
        self.assertEqual(("c",), index.get_parents_with_ghosts("a"))
 
808
        self.assertEqual(("a",), index.get_parents_with_ghosts("b"))
821
809
 
822
810
    def test_add_versions_random_id_is_accepted(self):
823
811
        transport = MockTransport([
902
890
        self.assertEqual(["opt1"], index.get_options("a"))
903
891
        self.assertEqual(["opt2", "opt3"], index.get_options("b"))
904
892
 
905
 
    def test_get_parents(self):
 
893
    def test_get_parent_map(self):
906
894
        transport = MockTransport([
907
895
            _KnitIndex.HEADER,
908
896
            "a option 0 1 :",
911
899
            ])
912
900
        index = self.get_knit_index(transport, "filename", "r")
913
901
 
914
 
        self.assertEqual([], index.get_parents("a"))
915
 
        self.assertEqual(["a", "c"], index.get_parents("b"))
916
 
        self.assertEqual(["b", "a"], index.get_parents("c"))
 
902
        self.assertEqual({
 
903
            "a":(),
 
904
            "b":("a", "c"),
 
905
            "c":("b", "a", "e"),
 
906
            }, index.get_parent_map(["a", "b", "c"]))
917
907
 
918
908
    def test_get_parents_with_ghosts(self):
919
909
        transport = MockTransport([
924
914
            ])
925
915
        index = self.get_knit_index(transport, "filename", "r")
926
916
 
927
 
        self.assertEqual([], index.get_parents_with_ghosts("a"))
928
 
        self.assertEqual(["a", "c"], index.get_parents_with_ghosts("b"))
929
 
        self.assertEqual(["b", "a", "e"],
 
917
        self.assertEqual((), index.get_parents_with_ghosts("a"))
 
918
        self.assertEqual(("a", "c"), index.get_parents_with_ghosts("b"))
 
919
        self.assertEqual(("b", "a", "e"),
930
920
            index.get_parents_with_ghosts("c"))
931
921
 
932
922
    def test_check_versions_present(self):
1221
1211
        """Store in knit with parents"""
1222
1212
        k = self.make_test_knit()
1223
1213
        self.add_stock_one_and_one_a(k)
1224
 
        self.assertEquals(k.get_parents('text-1'), [])
1225
 
        self.assertEquals(k.get_parents('text-1a'), ['text-1'])
 
1214
        self.assertEqual({'text-1':(), 'text-1a':('text-1',)},
 
1215
            k.get_parent_map(['text-1', 'text-1a']))
1226
1216
 
1227
1217
    def test_ancestry(self):
1228
1218
        """Store in knit with parents"""
1443
1433
            instrumented_t._activity)
1444
1434
        self.assertEqual([('text\n', 'base'), ('text2\n', 'base2')], results)
1445
1435
 
1446
 
    def test_create_empty_annotated(self):
1447
 
        k1 = self.make_test_knit(True)
1448
 
        # 0
1449
 
        k1.add_lines('text-a', [], ['a\n', 'b\n'])
1450
 
        k2 = k1.create_empty('t', MemoryTransport())
1451
 
        self.assertTrue(isinstance(k2.factory, KnitAnnotateFactory))
1452
 
        self.assertEqual(k1.delta, k2.delta)
1453
 
        # the generic test checks for empty content and file class
1454
 
 
1455
1436
    def test_knit_format(self):
1456
1437
        # this tests that a new knit index file has the expected content
1457
1438
        # and that is writes the data we expect as records are added.
1485
1466
        # and when reading it revid3 should now appear.
1486
1467
        knit = KnitVersionedFile('test', get_transport('.'), access_mode='r')
1487
1468
        self.assertEqual(['revid', 'revid2', 'revid3'], knit.versions())
1488
 
        self.assertEqual(['revid2'], knit.get_parents('revid3'))
 
1469
        self.assertEqual({'revid3':('revid2',)}, knit.get_parent_map(['revid3']))
1489
1470
 
1490
1471
    def test_delay_create(self):
1491
1472
        """Test that passing delay_create=True creates files late"""
1601
1582
            ]
1602
1583
        expected_data_list = [
1603
1584
            # version, options, length, parents
1604
 
            ('text-a', ['fulltext'], 122, []),
 
1585
            ('text-a', ['fulltext'], 122, ()),
1605
1586
           ]
1606
1587
        for version_id, parents, lines in test_data:
1607
1588
            k1.add_lines(version_id, parents, split_lines(lines))
1630
1611
            ]
1631
1612
        expected_data_list = [
1632
1613
            # version, options, length, parents
1633
 
            ('text-m', ['line-delta'], 84, ['text-b', 'text-d']),
 
1614
            ('text-m', ['line-delta'], 84, ('text-b', 'text-d')),
1634
1615
            ]
1635
1616
        for version_id, parents, lines in test_data:
1636
1617
            k1.add_lines(version_id, parents, split_lines(lines))
1660
1641
        original_versions = k1.versions
1661
1642
        k1.versions = lambda: reversed(original_versions())
1662
1643
        expected_data_list = [
1663
 
            ('text-a', ['fulltext'], 122, []),
1664
 
            ('text-b', ['line-delta'], 84, ['text-a'])]
 
1644
            ('text-a', ['fulltext'], 122, ()),
 
1645
            ('text-b', ['line-delta'], 84, ('text-a',))]
1665
1646
        # now check the fulltext is first and the delta second
1666
1647
        format, data_list, _ = k1.get_data_stream(['text-a', 'text-b'])
1667
1648
        self.assertEqual('knit-plain', format)
1673
1654
        format, data_list, _ = k1.get_data_stream([
1674
1655
            'text-m', 'text-b', 'text-a'])
1675
1656
        self.assertEqual([
1676
 
            ('text-a', ['fulltext'], 122, []),
1677
 
            ('text-b', ['line-delta'], 84, ['text-a']),
1678
 
            ('text-m', ['line-delta'], 84, ['text-b', 'text-d']),
 
1657
            ('text-a', ['fulltext'], 122, ()),
 
1658
            ('text-b', ['line-delta'], 84, ('text-a',)),
 
1659
            ('text-m', ['line-delta'], 84, ('text-b', 'text-d')),
1679
1660
            ], data_list)
1680
1661
 
1681
1662
    def test_get_stream_ghost_parent(self):
1688
1669
        # Expected data
1689
1670
        expected_data_list = [
1690
1671
            # version, options, length, parents
1691
 
            ('text-b', ['line-delta'], 84, ['text-a', 'text-ghost']),
 
1672
            ('text-b', ['line-delta'], 84, ('text-a', 'text-ghost')),
1692
1673
            ]
1693
1674
        
1694
1675
        format, data_list, reader_callable = k1.get_data_stream(['text-b'])
1716
1697
        # behaviour.
1717
1698
        expected_data_list = [
1718
1699
            # version, options, length, parents
1719
 
            ('text-d', ['line-delta'], 84, ['text-c']),
1720
 
            ('text-b', ['line-delta'], 84, ['text-a']),
 
1700
            ('text-d', ['line-delta'], 84, ('text-c',)),
 
1701
            ('text-b', ['line-delta'], 84, ('text-a',)),
1721
1702
            ]
1722
1703
        # Note that even though we request the revision IDs in a particular
1723
1704
        # order, the data stream may return them in any order it likes.  In this
1758
1739
        # behaviour.
1759
1740
        expected_data_list = [
1760
1741
            # version, options, length, parents
1761
 
            ('text-a', ['fulltext'], 122, []),
1762
 
            ('text-b', ['line-delta'], 84, ['text-a']),
1763
 
            ('text-m', ['line-delta'], 84, ['text-b', 'text-d']),
1764
 
            ('text-c', ['fulltext'], 121, []),
1765
 
            ('text-d', ['line-delta'], 84, ['text-c']),
 
1742
            ('text-a', ['fulltext'], 122, ()),
 
1743
            ('text-b', ['line-delta'], 84, ('text-a',)),
 
1744
            ('text-m', ['line-delta'], 84, ('text-b', 'text-d')),
 
1745
            ('text-c', ['fulltext'], 121, ()),
 
1746
            ('text-d', ['line-delta'], 84, ('text-c',)),
1766
1747
            ]
1767
1748
        format, data_list, reader_callable = k1.get_data_stream(
1768
1749
            ['text-a', 'text-b', 'text-c', 'text-d', 'text-m'])
1895
1876
        # The target knit object is in a consistent state, i.e. the record we
1896
1877
        # just added is immediately visible.
1897
1878
        self.assertTrue(target.has_version('text-a'))
1898
 
        self.assertTrue(target.has_ghost('text-ghost'))
 
1879
        self.assertFalse(target.has_version('text-ghost'))
 
1880
        self.assertEqual({'text-a':('text-ghost',)},
 
1881
            target.get_parent_map(['text-a', 'text-ghost']))
1899
1882
        self.assertEqual(split_lines(TEXT_1), target.get_lines('text-a'))
1900
1883
 
1901
1884
    def test_insert_data_stream_inconsistent_version_lines(self):
1941
1924
            errors.KnitDataStreamUnknown,
1942
1925
            target.insert_data_stream, data_stream)
1943
1926
 
 
1927
    def test_insert_data_stream_bug_208418(self):
 
1928
        """You can insert a stream with an incompatible format, even when:
 
1929
          * the stream has a line-delta record,
 
1930
          * whose parent is in the target, also stored as a line-delta
 
1931
 
 
1932
        See <https://launchpad.net/bugs/208418>.
 
1933
        """
 
1934
        base_lines = split_lines(TEXT_1)
 
1935
        # Make the target
 
1936
        target = self.make_test_knit(name='target', annotate=True)
 
1937
        target.add_lines('version-1', [], base_lines)
 
1938
        target.add_lines('version-2', ['version-1'], base_lines + ['a\n'])
 
1939
        # The second record should be a delta.
 
1940
        self.assertEqual('line-delta', target._index.get_method('version-2'))
 
1941
        
 
1942
        # Make a source, with a different format, but the same data
 
1943
        source = self.make_test_knit(name='source', annotate=False)
 
1944
        source.add_lines('version-1', [], base_lines)
 
1945
        source.add_lines('version-2', ['version-1'], base_lines + ['a\n'])
 
1946
        # Now add another record, which should be stored as a delta against
 
1947
        # version-2.
 
1948
        source.add_lines('version-3', ['version-2'], base_lines + ['b\n'])
 
1949
        self.assertEqual('line-delta', source._index.get_method('version-3'))
 
1950
 
 
1951
        # Make a stream of the new version
 
1952
        data_stream = source.get_data_stream(['version-3'])
 
1953
        # And insert into the target
 
1954
        target.insert_data_stream(data_stream)
 
1955
        # No errors should have been raised.
 
1956
 
 
1957
 
1944
1958
    #  * test that a stream of "already present version, then new version"
1945
1959
    #    inserts correctly.
1946
1960
 
2185
2199
            'a-3 fulltext 0 0 1 :'
2186
2200
            )
2187
2201
        self.assertEqual(['a-1', 'a-2', 'a-3'], idx._history)
2188
 
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, [], 0),
2189
 
                          'a-2':('a-2', ['fulltext'], 0, 0, ['a-1'], 1),
2190
 
                          'a-3':('a-3', ['fulltext'], 0, 0, ['a-2'], 2),
 
2202
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0),
 
2203
                          'a-2':('a-2', ['fulltext'], 0, 0, ('a-1',), 1),
 
2204
                          'a-3':('a-3', ['fulltext'], 0, 0, ('a-2',), 2),
2191
2205
                         }, idx._cache)
2192
2206
 
2193
2207
    def test_add_versions_fails_clean(self):
2211
2225
 
2212
2226
        def generate_failure():
2213
2227
            """Add some entries and then raise an exception"""
2214
 
            yield ('a-2', ['fulltext'], (None, 0, 0), ['a-1'])
2215
 
            yield ('a-3', ['fulltext'], (None, 0, 0), ['a-2'])
 
2228
            yield ('a-2', ['fulltext'], (None, 0, 0), ('a-1',))
 
2229
            yield ('a-3', ['fulltext'], (None, 0, 0), ('a-2',))
2216
2230
            raise StopEarly()
2217
2231
 
2218
2232
        # Assert the pre-condition
2219
2233
        self.assertEqual(['a-1'], idx._history)
2220
 
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, [], 0)}, idx._cache)
 
2234
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0)}, idx._cache)
2221
2235
 
2222
2236
        self.assertRaises(StopEarly, idx.add_versions, generate_failure())
2223
2237
 
2224
2238
        # And it shouldn't be modified
2225
2239
        self.assertEqual(['a-1'], idx._history)
2226
 
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, [], 0)}, idx._cache)
 
2240
        self.assertEqual({'a-1':('a-1', ['fulltext'], 0, 0, (), 0)}, idx._cache)
2227
2241
 
2228
2242
    def test_knit_index_ignores_empty_files(self):
2229
2243
        # There was a race condition in older bzr, where a ^C at the right time
2287
2301
        return KnitGraphIndex(combined_index, deltas=deltas,
2288
2302
            add_callback=add_callback)
2289
2303
 
2290
 
    def test_get_graph(self):
2291
 
        index = self.two_graph_index()
2292
 
        self.assertEqual(set([
2293
 
            ('tip', ('parent', )),
2294
 
            ('tail', ()),
2295
 
            ('parent', ('tail', 'ghost')),
2296
 
            ('separate', ()),
2297
 
            ]), set(index.get_graph()))
2298
 
 
2299
2304
    def test_get_ancestry(self):
2300
2305
        # get_ancestry is defined as eliding ghosts, not erroring.
2301
2306
        index = self.two_graph_index()
2385
2390
        self.assertEqual(['fulltext', 'no-eol'], index.get_options('tip'))
2386
2391
        self.assertEqual(['fulltext'], index.get_options('parent'))
2387
2392
 
2388
 
    def test_get_parents(self):
2389
 
        # get_parents ignores ghosts
2390
 
        index = self.two_graph_index()
2391
 
        self.assertEqual(('tail', ), index.get_parents('parent'))
2392
 
        # and errors on ghosts.
2393
 
        self.assertRaises(errors.RevisionNotPresent,
2394
 
            index.get_parents, 'ghost')
2395
 
 
2396
2393
    def test_get_parents_with_ghosts(self):
2397
2394
        index = self.two_graph_index()
2398
2395
        self.assertEqual(('tail', 'ghost'), index.get_parents_with_ghosts('parent'))
2593
2590
        return KnitGraphIndex(combined_index, parents=False,
2594
2591
            add_callback=add_callback)
2595
2592
 
2596
 
    def test_get_graph(self):
2597
 
        index = self.two_graph_index()
2598
 
        self.assertEqual(set([
2599
 
            ('tip', ()),
2600
 
            ('tail', ()),
2601
 
            ('parent', ()),
2602
 
            ('separate', ()),
2603
 
            ]), set(index.get_graph()))
2604
 
 
2605
2593
    def test_get_ancestry(self):
2606
2594
        # with no parents, ancestry is always just the key.
2607
2595
        index = self.two_graph_index()
2660
2648
        self.assertEqual(['fulltext', 'no-eol'], index.get_options('tip'))
2661
2649
        self.assertEqual(['fulltext'], index.get_options('parent'))
2662
2650
 
2663
 
    def test_get_parents(self):
2664
 
        index = self.two_graph_index()
2665
 
        self.assertEqual((), index.get_parents('parent'))
2666
 
        # and errors on ghosts.
2667
 
        self.assertRaises(errors.RevisionNotPresent,
2668
 
            index.get_parents, 'ghost')
2669
 
 
2670
2651
    def test_get_parents_with_ghosts(self):
2671
2652
        index = self.two_graph_index()
2672
2653
        self.assertEqual((), index.get_parents_with_ghosts('parent'))
2929
2910
 
2930
2911
    def test_iter_parents(self):
2931
2912
        knit = self.make_knit_with_4_versions_2_dags()
2932
 
        self.assertIterParents(knit, ['a'], ['a'], [('a', [])])
 
2913
        self.assertIterParents(knit, ['a'], ['a'], [('a', ())])
2933
2914
        self.assertIterParents(knit, ['a', 'b'], ['a', 'b'],
2934
 
            [('a', []), ('b', [])])
 
2915
            [('a', ()), ('b', ())])
2935
2916
        self.assertIterParents(knit, ['a', 'b', 'c'], ['a', 'b', 'c'],
2936
 
            [('a', []), ('b', []), ('c', ['b', 'a'])])
 
2917
            [('a', ()), ('b', ()), ('c', ('b', 'a'))])
2937
2918
        self.assertIterParents(knit, ['a', 'b', 'c', 'd'],
2938
2919
            ['a', 'b', 'c', 'd'],
2939
 
            [('a', []), ('b', []), ('c', ['b', 'a']), ('d', ['e', 'f'])])
 
2920
            [('a', ()), ('b', ()), ('c', ('b', 'a')), ('d', ('e', 'f'))])
2940
2921
        self.assertIterParents(knit, ['c'], ['a', 'b', 'c'],
2941
 
            [('c', ['b', 'a'])])
 
2922
            [('c', ('b', 'a'))])
2942
2923
 
2943
2924
    def test_get_options(self):
2944
2925
        knit = self.make_knit_with_4_versions_2_dags()
2947
2928
 
2948
2929
    def test_get_parents_with_ghosts(self):
2949
2930
        knit = self.make_knit_with_4_versions_2_dags()
2950
 
        self.assertGetParentsWithGhosts(knit, ['a'], 'a', [])
2951
 
        self.assertGetParentsWithGhosts(knit, ['c'], 'c', ['b', 'a'])
2952
 
        self.assertGetParentsWithGhosts(knit, ['d'], 'd', ['e', 'f'])
 
2931
        self.assertGetParentsWithGhosts(knit, ['a'], 'a', ())
 
2932
        self.assertGetParentsWithGhosts(knit, ['c'], 'c', ('b', 'a'))
 
2933
        self.assertGetParentsWithGhosts(knit, ['d'], 'd', ('e', 'f'))
2953
2934
 
2954
2935
    def test_get_position(self):
2955
2936
        knit = self.make_knit_with_4_versions_2_dags()