424
424
def __init__(self, parents_provider):
426
426
self._real_parents_provider = parents_provider
427
get_cached = getattr(parents_provider, 'get_cached_parent_map', None)
428
if get_cached is not None:
429
# Only expose the underlying 'get_cached_parent_map' function if
430
# the wrapped provider has it.
431
self.get_cached_parent_map = self._get_cached_parent_map
428
433
def get_parent_map(self, nodes):
429
434
self.calls.extend(nodes)
430
435
return self._real_parents_provider.get_parent_map(nodes)
437
def _get_cached_parent_map(self, nodes):
438
self.calls.append(('cached', sorted(nodes)))
439
return self._real_parents_provider.get_cached_parent_map(nodes)
442
class SharedInstrumentedParentsProvider(object):
444
def __init__(self, parents_provider, calls, info):
447
self._real_parents_provider = parents_provider
448
get_cached = getattr(parents_provider, 'get_cached_parent_map', None)
449
if get_cached is not None:
450
# Only expose the underlying 'get_cached_parent_map' function if
451
# the wrapped provider has it.
452
self.get_cached_parent_map = self._get_cached_parent_map
454
def get_parent_map(self, nodes):
455
self.calls.append((self.info, sorted(nodes)))
456
return self._real_parents_provider.get_parent_map(nodes)
458
def _get_cached_parent_map(self, nodes):
459
self.calls.append((self.info, 'cached', sorted(nodes)))
460
return self._real_parents_provider.get_cached_parent_map(nodes)
433
463
class TestGraphBase(tests.TestCase):
673
703
self.assertEqual((set(['e']), set(['f', 'g'])),
674
704
graph.find_difference('e', 'f'))
677
def test_stacked_parents_provider(self):
678
parents1 = _mod_graph.DictParentsProvider({'rev2': ['rev3']})
679
parents2 = _mod_graph.DictParentsProvider({'rev1': ['rev4']})
680
stacked = _mod_graph.StackedParentsProvider([parents1, parents2])
681
self.assertEqual({'rev1':['rev4'], 'rev2':['rev3']},
682
stacked.get_parent_map(['rev1', 'rev2']))
683
self.assertEqual({'rev2':['rev3'], 'rev1':['rev4']},
684
stacked.get_parent_map(['rev2', 'rev1']))
685
self.assertEqual({'rev2':['rev3']},
686
stacked.get_parent_map(['rev2', 'rev2']))
687
self.assertEqual({'rev1':['rev4']},
688
stacked.get_parent_map(['rev1', 'rev1']))
690
def test_stacked_parents_provider_overlapping(self):
691
# rev2 is availible in both providers.
695
parents1 = _mod_graph.DictParentsProvider({'rev2': ['rev1']})
696
parents2 = _mod_graph.DictParentsProvider({'rev2': ['rev1']})
697
stacked = _mod_graph.StackedParentsProvider([parents1, parents2])
698
self.assertEqual({'rev2': ['rev1']},
699
stacked.get_parent_map(['rev2']))
701
706
def test_iter_topo_order(self):
702
707
graph = self.make_graph(ancestry_1)
703
708
args = ['rev2a', 'rev3', 'rev1']
1518
1523
self.assertEqual([], self.inst_pp.calls)
1519
1524
self.assertEqual(set(['b']), self.caching_pp.missing_keys)
1526
def test_get_cached_parent_map(self):
1527
self.assertEqual({}, self.caching_pp.get_cached_parent_map(['a']))
1528
self.assertEqual([], self.inst_pp.calls)
1529
self.assertEqual({'a': ('b',)}, self.caching_pp.get_parent_map(['a']))
1530
self.assertEqual(['a'], self.inst_pp.calls)
1531
self.assertEqual({'a': ('b',)},
1532
self.caching_pp.get_cached_parent_map(['a']))
1522
1535
class TestCachingParentsProviderExtras(tests.TestCaseWithTransport):
1523
1536
"""Test the behaviour when parents are provided that were not requested."""
1815
1836
extended_history_shortcut, (), ['a'], 1)
1816
1837
self.assertSearchResult(['f'], ['a'], 4,
1817
1838
extended_history_shortcut, (), ['a'], 2)
1841
class TestStackedParentsProvider(tests.TestCase):
1844
super(TestStackedParentsProvider, self).setUp()
1847
def get_shared_provider(self, info, ancestry, has_cached):
1848
pp = _mod_graph.DictParentsProvider(ancestry)
1850
pp.get_cached_parent_map = pp.get_parent_map
1851
return SharedInstrumentedParentsProvider(pp, self.calls, info)
1853
def test_stacked_parents_provider(self):
1854
parents1 = _mod_graph.DictParentsProvider({'rev2': ['rev3']})
1855
parents2 = _mod_graph.DictParentsProvider({'rev1': ['rev4']})
1856
stacked = _mod_graph.StackedParentsProvider([parents1, parents2])
1857
self.assertEqual({'rev1':['rev4'], 'rev2':['rev3']},
1858
stacked.get_parent_map(['rev1', 'rev2']))
1859
self.assertEqual({'rev2':['rev3'], 'rev1':['rev4']},
1860
stacked.get_parent_map(['rev2', 'rev1']))
1861
self.assertEqual({'rev2':['rev3']},
1862
stacked.get_parent_map(['rev2', 'rev2']))
1863
self.assertEqual({'rev1':['rev4']},
1864
stacked.get_parent_map(['rev1', 'rev1']))
1866
def test_stacked_parents_provider_overlapping(self):
1867
# rev2 is availible in both providers.
1871
parents1 = _mod_graph.DictParentsProvider({'rev2': ['rev1']})
1872
parents2 = _mod_graph.DictParentsProvider({'rev2': ['rev1']})
1873
stacked = _mod_graph.StackedParentsProvider([parents1, parents2])
1874
self.assertEqual({'rev2': ['rev1']},
1875
stacked.get_parent_map(['rev2']))
1877
def test_handles_no_get_cached_parent_map(self):
1878
# this shows that we both handle when a provider doesn't implement
1879
# get_cached_parent_map
1880
pp1 = self.get_shared_provider('pp1', {'rev2': ('rev1',)},
1882
pp2 = self.get_shared_provider('pp2', {'rev2': ('rev1',)},
1884
stacked = _mod_graph.StackedParentsProvider([pp1, pp2])
1885
self.assertEqual({'rev2': ('rev1',)}, stacked.get_parent_map(['rev2']))
1886
# No call on 'pp1' because it doesn't provide get_cached_parent_map
1887
self.assertEqual([('pp2', 'cached', ['rev2'])], self.calls)
1889
def test_query_order(self):
1890
# We should call get_cached_parent_map on all providers before we call
1891
# get_parent_map. Further, we should track what entries we have found,
1892
# and not re-try them.
1893
pp1 = self.get_shared_provider('pp1', {'a': ()}, has_cached=True)
1894
pp2 = self.get_shared_provider('pp2', {'c': ('b',)}, has_cached=False)
1895
pp3 = self.get_shared_provider('pp3', {'b': ('a',)}, has_cached=True)
1896
stacked = _mod_graph.StackedParentsProvider([pp1, pp2, pp3])
1897
self.assertEqual({'a': (), 'b': ('a',), 'c': ('b',)},
1898
stacked.get_parent_map(['a', 'b', 'c', 'd']))
1899
self.assertEqual([('pp1', 'cached', ['a', 'b', 'c', 'd']),
1900
# No call to pp2, because it doesn't have cached
1901
('pp3', 'cached', ['b', 'c', 'd']),
1902
('pp1', ['c', 'd']),
1903
('pp2', ['c', 'd']),