1082
1082
search = graph._make_breadth_first_searcher(['head'])
1083
1083
self.assertSeenAndResult(expected, search, search.next_with_ghosts)
1085
def test_breadth_first_stop_searching_late(self):
1086
# A client should be able to say 'stop node X' and have it excluded
1087
# from the result even if X was seen in an older iteration of the
1089
graph = self.make_graph({
1092
'child':[NULL_REVISION],
1095
search = graph._make_breadth_first_searcher(['head'])
1097
(set(['head']), (set(['head']), set(['middle']), 1),
1098
['head'], None, None),
1099
(set(['head', 'middle']), (set(['head']), set(['child']), 2),
1100
['head', 'middle'], None, None),
1101
# 'middle' came from the previous iteration, but we don't stop
1102
# searching it until *after* advancing the searcher.
1103
(set(['head', 'middle', 'child']),
1104
(set(['head']), set(['middle', 'child']), 1),
1105
['head'], None, ['middle', 'child']),
1107
self.assertSeenAndResult(expected, search, search.next)
1108
# using next_with_ghosts:
1109
search = graph._make_breadth_first_searcher(['head'])
1110
self.assertSeenAndResult(expected, search, search.next_with_ghosts)
1085
1112
def test_breadth_first_get_result_ghosts_are_excluded(self):
1086
1113
graph = self.make_graph({
1087
1114
'head':['child', 'ghost'],
1386
1413
self.assertEqual(['a', 'b'], sorted(self.inst_pp.calls))
1416
class TestCachingParentsProviderExtras(tests.TestCaseWithTransport):
1417
"""Test the behaviour when parents are provided that were not requested."""
1420
super(TestCachingParentsProviderExtras, self).setUp()
1421
class ExtraParentsProvider(object):
1423
def get_parent_map(self, keys):
1424
return {'rev1': [], 'rev2': ['rev1',]}
1426
self.inst_pp = InstrumentedParentsProvider(ExtraParentsProvider())
1427
self.caching_pp = _mod_graph.CachingParentsProvider(
1428
get_parent_map=self.inst_pp.get_parent_map)
1430
def test_uncached(self):
1431
self.caching_pp.disable_cache()
1432
self.assertEqual({'rev1': []},
1433
self.caching_pp.get_parent_map(['rev1']))
1434
self.assertEqual(['rev1'], self.inst_pp.calls)
1435
self.assertIs(None, self.caching_pp._cache)
1437
def test_cache_initially_empty(self):
1438
self.assertEqual({}, self.caching_pp._cache)
1440
def test_cached(self):
1441
self.assertEqual({'rev1': []},
1442
self.caching_pp.get_parent_map(['rev1']))
1443
self.assertEqual(['rev1'], self.inst_pp.calls)
1444
self.assertEqual({'rev1': [], 'rev2': ['rev1']},
1445
self.caching_pp._cache)
1446
self.assertEqual({'rev1': []},
1447
self.caching_pp.get_parent_map(['rev1']))
1448
self.assertEqual(['rev1'], self.inst_pp.calls)
1450
def test_disable_cache_clears_cache(self):
1451
# Put something in the cache
1452
self.caching_pp.get_parent_map(['rev1'])
1453
self.assertEqual(2, len(self.caching_pp._cache))
1454
self.caching_pp.disable_cache()
1455
self.assertIs(None, self.caching_pp._cache)
1457
def test_enable_cache_raises(self):
1458
e = self.assertRaises(AssertionError, self.caching_pp.enable_cache)
1459
self.assertEqual('Cache enabled when already enabled.', str(e))
1461
def test_cache_misses(self):
1462
self.caching_pp.get_parent_map(['rev3'])
1463
self.caching_pp.get_parent_map(['rev3'])
1464
self.assertEqual(['rev3'], self.inst_pp.calls)
1466
def test_no_cache_misses(self):
1467
self.caching_pp.disable_cache()
1468
self.caching_pp.enable_cache(cache_misses=False)
1469
self.caching_pp.get_parent_map(['rev3'])
1470
self.caching_pp.get_parent_map(['rev3'])
1471
self.assertEqual(['rev3', 'rev3'], self.inst_pp.calls)
1473
def test_cache_extras(self):
1474
self.assertEqual({}, self.caching_pp.get_parent_map(['rev3']))
1475
self.assertEqual({'rev2': ['rev1']},
1476
self.caching_pp.get_parent_map(['rev2']))
1477
self.assertEqual(['rev3'], self.inst_pp.calls)
1389
1480
class TestCollapseLinearRegions(tests.TestCase):
1391
1482
def assertCollapsed(self, collapsed, original):