summaryrefslogtreecommitdiff
path: root/bzrlib/tests/per_repository_reference/test_graph.py
diff options
context:
space:
mode:
Diffstat (limited to 'bzrlib/tests/per_repository_reference/test_graph.py')
-rw-r--r--bzrlib/tests/per_repository_reference/test_graph.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/bzrlib/tests/per_repository_reference/test_graph.py b/bzrlib/tests/per_repository_reference/test_graph.py
new file mode 100644
index 0000000..e60dab9
--- /dev/null
+++ b/bzrlib/tests/per_repository_reference/test_graph.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+"""Tests for graph operations on stacked repositories."""
+
+
+from bzrlib import (
+ remote,
+ tests,
+ urlutils,
+ )
+from bzrlib.tests.per_repository import TestCaseWithRepository
+
+
+class TestGraph(TestCaseWithRepository):
+
+ def test_get_known_graph_ancestry_stacked(self):
+ """get_known_graph_ancestry works correctly on stacking.
+
+ See <https://bugs.launchpad.net/bugs/715000>.
+ """
+ branch_a, branch_b, branch_c, revid_1 = self.make_double_stacked_branches()
+ for br in [branch_a, branch_b, branch_c]:
+ self.assertEquals(
+ [revid_1],
+ br.repository.get_known_graph_ancestry([revid_1]).topo_sort())
+
+ def make_double_stacked_branches(self):
+ wt_a = self.make_branch_and_tree('a')
+ branch_a = wt_a.branch
+ branch_b = self.make_branch('b')
+ branch_b.set_stacked_on_url(
+ urlutils.relative_url(branch_b.base, branch_a.base))
+ branch_c = self.make_branch('c')
+ branch_c.set_stacked_on_url(
+ urlutils.relative_url(branch_c.base, branch_b.base))
+ revid_1 = wt_a.commit('first commit')
+ return branch_a, branch_b, branch_c, revid_1
+
+ def make_stacked_branch_with_long_history(self):
+ builder = self.make_branch_builder('source')
+ builder.start_series()
+ builder.build_snapshot('A', None, [
+ ('add', ('', 'directory', 'root-id', None))])
+ builder.build_snapshot('B', ['A'], [])
+ builder.build_snapshot('C', ['B'], [])
+ builder.build_snapshot('D', ['C'], [])
+ builder.build_snapshot('E', ['D'], [])
+ builder.build_snapshot('F', ['E'], [])
+ source_b = builder.get_branch()
+ master_b = self.make_branch('master')
+ master_b.pull(source_b, stop_revision='E')
+ stacked_b = self.make_branch('stacked')
+ stacked_b.set_stacked_on_url('../master')
+ stacked_b.pull(source_b, stop_revision='F')
+ builder.finish_series()
+ return master_b, stacked_b
+
+ def assertParentMapCalls(self, expected):
+ """Check that self.hpss_calls has the expected get_parent_map calls."""
+ get_parent_map_calls = []
+ for c in self.hpss_calls:
+ # Right now, the only RPCs that get called are get_parent_map. If
+ # this changes in the future, we can change this to:
+ # if c.call.method != 'Repository.get_parent_map':
+ # continue
+ self.assertEqual('Repository.get_parent_map', c.call.method)
+ args = c.call.args
+ location = args[0]
+ self.assertEqual('include-missing:', args[1])
+ revisions = sorted(args[2:])
+ get_parent_map_calls.append((location, revisions))
+ self.assertEqual(expected, get_parent_map_calls)
+
+ def test_doesnt_call_get_parent_map_on_all_fallback_revs(self):
+ if not isinstance(self.repository_format,
+ remote.RemoteRepositoryFormat):
+ raise tests.TestNotApplicable('only for RemoteRepository')
+ # bug #388269
+ master_b, stacked_b = self.make_stacked_branch_with_long_history()
+ self.addCleanup(stacked_b.lock_read().unlock)
+ self.make_repository('target_repo', shared=True)
+ target_b = self.make_branch('target_repo/branch')
+ self.addCleanup(target_b.lock_write().unlock)
+ self.setup_smart_server_with_call_log()
+ res = target_b.repository.search_missing_revision_ids(
+ stacked_b.repository, revision_ids=['F'],
+ find_ghosts=False)
+ self.assertParentMapCalls([
+ # One call to stacked to start, which returns F=>E, and that E
+ # itself is missing, so when we step, we won't look for it.
+ ('extra/stacked/', ['F']),
+ # One fallback call to extra/master, which will return the rest of
+ # the history.
+ ('extra/master/', ['E']),
+ # And then one get_parent_map call to the target, to see if it
+ # already has any of these revisions.
+ ('extra/target_repo/branch/', ['A', 'B', 'C', 'D', 'E', 'F']),
+ ])
+ # Before bug #388269 was fixed, there would be a bunch of extra calls
+ # to 'extra/stacked', ['D'] then ['C'], then ['B'], then ['A'].
+ # One-at-a-time for the rest of the ancestry.