Rev 417: Test some edge cases for get_revids_from and test_iter. in http://bazaar.launchpad.net/~jameinel/loggerhead/page_loading
John Arbash Meinel
john at arbash-meinel.com
Mon Mar 14 14:48:01 UTC 2011
At http://bazaar.launchpad.net/~jameinel/loggerhead/page_loading
------------------------------------------------------------
revno: 417
revision-id: john at arbash-meinel.com-20110314144748-blc0zub6x7u8nf2m
parent: john at arbash-meinel.com-20110312152740-9uq3n0m1zbz194s7
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: page_loading
timestamp: Mon 2011-03-14 15:47:48 +0100
message:
Test some edge cases for get_revids_from and test_iter.
We can track what revisions we have 'introduced' and then stop looking
for them. Once we have found everything we introduced, we can stop early.
-------------- next part --------------
=== modified file 'loggerhead/history.py'
--- a/loggerhead/history.py 2011-03-12 15:27:40 +0000
+++ b/loggerhead/history.py 2011-03-14 14:47:48 +0000
@@ -348,10 +348,14 @@
r.add(self._rev_info[i][0][1])
i += 1
return r
- while True:
+ while revid_set:
if bzrlib.revision.is_null(revid):
return
- if introduced_revisions(revid) & revid_set:
+ rev_introduced = introduced_revisions(revid)
+ matching = rev_introduced.intersection(revid_set)
+ if matching:
+ # We don't need to look for these anymore.
+ revid_set.difference_update(matching)
yield revid
parents = self._rev_info[self._rev_indices[revid]][2]
if len(parents) == 0:
=== modified file 'loggerhead/tests/test_history.py'
--- a/loggerhead/tests/test_history.py 2011-03-12 15:27:40 +0000
+++ b/loggerhead/tests/test_history.py 2011-03-14 14:47:48 +0000
@@ -22,7 +22,8 @@
from loggerhead import history
-class TestHistoryGetRevidsFrom(tests.TestCaseWithMemoryTransport):
+class TestCaseWithExamples(tests.TestCaseWithMemoryTransport):
+
def make_linear_ancestry(self):
# Time goes up
@@ -42,6 +43,18 @@
self.addCleanup(b.lock_read().unlock)
return history.History(b, {})
+ def make_long_linear_ancestry(self):
+ builder = self.make_branch_builder('branch')
+ builder.start_series()
+ builder.build_snapshot('A', None, [
+ ('add', ('', 'root-id', 'directory', None))])
+ for r in "BCDEFGHIJKLMNOPQRSTUVWXYZ":
+ builder.build_snapshot(r, None, [])
+ builder.finish_series()
+ b = builder.get_branch()
+ self.addCleanup(b.lock_read().unlock)
+ return history.History(b, {})
+
def make_merged_ancestry(self):
# Time goes up
# rev-3
@@ -85,6 +98,41 @@
self.addCleanup(b.lock_read().unlock)
return history.History(b, {})
+
+class TestHistory(TestCaseWithExamples):
+
+ def test_get_file_view_iterable(self):
+ # We want to make sure that get_file_view returns an iterator, rather
+ # than pre-loading all history.
+ pass
+
+
+class _DictProxy(object):
+
+ def __init__(self, d):
+ self._d = d
+ self._accessed = set()
+ self.__setitem__ = d.__setitem__
+
+ def __getitem__(self, name):
+ self._accessed.add(name)
+ return self._d[name]
+
+ def __len__(self):
+ return len(self._d)
+
+
+def track_rev_info_accesses(h):
+ """Track __getitem__ access to History._rev_info,
+
+ :return: set of items accessed
+ """
+ h._rev_info = _DictProxy(h._rev_info)
+ return h._rev_info._accessed
+
+
+class TestHistoryGetRevidsFrom(TestCaseWithExamples):
+
def assertRevidsFrom(self, expected, his, search_revs, tip_rev):
self.assertEqual(expected,
list(his.get_revids_from(search_revs, tip_rev)))
@@ -113,6 +161,33 @@
self.assertRevidsFrom(['B'], his, ['B'], 'F')
self.assertRevidsFrom(['A'], his, ['A'], 'F')
+ def test_get_revids_doesnt_over_produce_simple_mainline(self):
+ # get_revids_from shouldn't walk the whole ancestry just to get the
+ # answers for the first few revisions.
+ his = self.make_long_linear_ancestry()
+ accessed = track_rev_info_accesses(his)
+ result = his.get_revids_from(None, 'Z')
+ self.assertEqual(set(), accessed)
+ self.assertEqual('Z', result.next())
+ # We already know 'Z' because we passed it in.
+ self.assertEqual(set(), accessed)
+ self.assertEqual('Y', result.next())
+ self.assertEqual(set([his._rev_indices['Z']]), accessed)
+
+ def test_get_revids_doesnt_over_produce_for_merges(self):
+ # get_revids_from shouldn't walk the whole ancestry just to get the
+ # answers for the first few revisions.
+ his = self.make_long_linear_ancestry()
+ accessed = track_rev_info_accesses(his)
+ result = his.get_revids_from(['X'], 'Z')
+ self.assertEqual(set(), accessed)
+ self.assertEqual('X', result.next())
+ # We access 'W' because we are checking that W wasn't merged into X.
+ # The important bit is that we aren't getting the whole ancestry.
+ self.assertEqual(set([his._rev_indices[x] for x in 'ZYXW']), accessed)
+ self.assertRaises(StopIteration, result.next)
+ self.assertEqual(set([his._rev_indices[x] for x in 'ZYXW']), accessed)
+
class TestHistory_IterateSufficiently(tests.TestCase):
@@ -140,3 +215,7 @@
lst = list('abcdefghijklmnopqrstuvwxyz')
self.assertIterate(lst, iter(lst), 'y', 10)
self.assertIterate(lst, iter(lst), 'z', 10)
+
+ def test_iter_with_extra_None(self):
+ lst = list('abcdefghijklmnopqrstuvwxyz')
+ self.assertIterate(lst, iter(lst), 'z', None)
More information about the bazaar-commits
mailing list