You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2012/10/16 16:27:08 UTC

[13/16] git commit: [#5094] Removed use of CommitRun by SVN repos

[#5094] Removed use of CommitRun by SVN repos

SVN repo histories are inherently linear, so the CommitRun doc is both
unneccesary and inefficient.

To make this change, I had to refactor the commit log building to live
in the Repository classes, where it really belongs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f88173a6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f88173a6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f88173a6

Branch: refs/heads/cj/5094
Commit: f88173a6f64f523cf5a83c9bab5fdf8528836ed1
Parents: 2a0b57c
Author: Cory Johns <jo...@geek.net>
Authored: Mon Oct 15 16:13:45 2012 +0000
Committer: Dave Brondsema <db...@geek.net>
Committed: Mon Oct 15 17:46:35 2012 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py          |    2 +-
 Allura/allura/model/repo.py                      |  107 ++---------------
 Allura/allura/model/repo_refresh.py              |   33 +++---
 Allura/allura/model/repository.py                |  102 +++++++++++++++-
 Allura/allura/tests/model/test_repo.py           |   30 ++---
 ForgeGit/forgegit/tests/model/test_repository.py |    9 +-
 ForgeHg/forgehg/tests/model/test_repository.py   |    9 +-
 ForgeSVN/forgesvn/model/svn.py                   |   25 +++-
 ForgeSVN/forgesvn/tests/model/test_repository.py |   14 ++-
 9 files changed, 175 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index c90b803..c321808 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -188,7 +188,7 @@ class RepoRootController(BaseController):
     @expose('json:')
     def commit_browser_data(self):
         head_ids = [ head.object_id for head in c.app.repo.heads ]
-        commit_ids = list(M.repo.commitlog(head_ids))
+        commit_ids = list(c.app.repo.commitlog(head_ids))
         log.info('Grab %d commit objects by ID', len(commit_ids))
         commits_by_id = dict(
             (c_obj._id, c_obj)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/Allura/allura/model/repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo.py b/Allura/allura/model/repo.py
index b991629..b82610c 100644
--- a/Allura/allura/model/repo.py
+++ b/Allura/allura/model/repo.py
@@ -3,7 +3,7 @@ import re
 import sys
 import logging
 from hashlib import sha1
-from itertools import izip, chain
+from itertools import chain
 from datetime import datetime
 from collections import defaultdict
 from difflib import SequenceMatcher, unified_diff
@@ -182,6 +182,14 @@ class Commit(RepoObject):
     def symbolic_ids(self):
         return self.repo.symbolics_for_commit(self)
 
+    def parent(self, index=0):
+        ci = None
+        if self.parent_ids:
+            ci = self.query.get(_id=self.parent_ids[index])
+        if ci:
+            ci.set_context(self.repo)
+        return ci
+
     def url(self):
         if self.repo is None: self.repo = self.guess_repo()
         if self.repo is None: return '#'
@@ -206,41 +214,6 @@ class Commit(RepoObject):
         '''
         return self.shorthand_id()
 
-    def log_iter(self, skip, count):
-        for oids in utils.chunked_iter(commitlog([self._id]), QSIZE):
-            oids = list(oids)
-            commits = dict(
-                (ci._id, ci) for ci in self.query.find(dict(
-                        _id={'$in': oids})))
-            for oid in oids:
-                if skip:
-                    skip -= 1
-                    continue
-                if count:
-                    count -= 1
-                    ci = commits[oid]
-                    ci.set_context(self.repo)
-                    yield ci
-                else:
-                    break
-
-    def log(self, skip, count):
-        return list(self.log_iter(skip, count))
-
-    def count_revisions(self):
-        from .repo_refresh import CommitRunBuilder
-        result = 0
-        # If there's no CommitRunDoc for this commit, the call to
-        # commitlog() below will raise a KeyError. Repair the CommitRuns for
-        # this repo by rebuilding them entirely.
-        if self.repo and not CommitRunDoc.m.find(dict(commit_ids=self._id)).count():
-            log.info('CommitRun incomplete, rebuilding with all commits')
-            rb = CommitRunBuilder(list(self.repo.all_commit_ids()))
-            rb.run()
-            rb.cleanup()
-        for oid in commitlog([self._id]): result += 1
-        return result
-
     def context(self):
         result = dict(prev=None, next=None)
         if self.parent_ids:
@@ -320,7 +293,7 @@ class Commit(RepoObject):
         if not removed:
             return []
         copied = []
-        prev_commit = self.log(1, 1)[0]
+        prev_commit = self.parent()
         for removed_name in removed[:]:
             removed_blob = prev_commit.tree.get_obj_by_path(removed_name)
             rename_info = None
@@ -598,63 +571,3 @@ class Blob(object):
 
 mapper(Commit, CommitDoc, repository_orm_session)
 mapper(Tree, TreeDoc, repository_orm_session)
-
-def commitlog(commit_ids, skip=0, limit=sys.maxint):
-    seen = set()
-    def _visit(commit_id):
-        if commit_id in seen: return
-        run = CommitRunDoc.m.get(commit_ids=commit_id)
-        if run is None: return
-        index = False
-        for pos, (oid, time) in enumerate(izip(run.commit_ids, run.commit_times)):
-            if oid == commit_id: index = True
-            elif not index: continue
-            seen.add(oid)
-            ci_times[oid] = time
-            if pos+1 < len(run.commit_ids):
-                ci_parents[oid] = [ run.commit_ids[pos+1] ]
-            else:
-                ci_parents[oid] = run.parent_commit_ids
-        for oid in run.parent_commit_ids:
-            if oid not in seen:
-                _visit(oid)
-
-    def _gen_ids(commit_ids, skip, limit):
-        # Traverse the graph in topo order, yielding commit IDs
-        commits = set(commit_ids)
-        new_parent = None
-        while commits and limit:
-            # next commit is latest commit that's valid to log
-            if new_parent in commits:
-                ci = new_parent
-            else:
-                ci = max(commits, key=lambda ci:ci_times[ci])
-            commits.remove(ci)
-            if skip:
-                skip -= 1
-                continue
-            else:
-                limit -= 1
-            yield ci
-            # remove this commit from its parents children and add any childless
-            # parents to the 'ready set'
-            new_parent = None
-            for oid in ci_parents.get(ci, []):
-                children = ci_children[oid]
-                children.discard(ci)
-                if not children:
-                    commits.add(oid)
-                    new_parent = oid
-
-    # Load all the runs to build a commit graph
-    ci_times = {}
-    ci_parents = {}
-    ci_children = defaultdict(set)
-    log.info('Build commit graph')
-    for cid in commit_ids:
-        _visit(cid)
-    for oid, parents in ci_parents.iteritems():
-        for ci_parent in parents:
-            ci_children[ci_parent].add(oid)
-
-    return _gen_ids(commit_ids, skip, limit)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/Allura/allura/model/repo_refresh.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo_refresh.py b/Allura/allura/model/repo_refresh.py
index 16b8dc1..7251fd1 100644
--- a/Allura/allura/model/repo_refresh.py
+++ b/Allura/allura/model/repo_refresh.py
@@ -57,22 +57,23 @@ def refresh_repo(repo, all_commits=False, notify=True):
         if (i+1) % 100 == 0:
             log.info('Refresh child info %d for parents of %s', (i+1), ci._id)
 
-    # Refresh commit runs
-    commit_run_ids = commit_ids
-    # Check if the CommitRuns for the repo are in a good state by checking for
-    # a CommitRunDoc that contains the last known commit. If there isn't one,
-    # the CommitRuns for this repo are in a bad state - rebuild them entirely.
-    if commit_run_ids != all_commit_ids:
-        last_commit = last_known_commit_id(all_commit_ids, new_commit_ids)
-        log.info('Last known commit id: %s', last_commit)
-        if not CommitRunDoc.m.find(dict(commit_ids=last_commit)).count():
-            log.info('CommitRun incomplete, rebuilding with all commits')
-            commit_run_ids = all_commit_ids
-    log.info('Starting CommitRunBuilder for %s', repo.full_fs_path)
-    rb = CommitRunBuilder(commit_run_ids)
-    rb.run()
-    rb.cleanup()
-    log.info('Finished CommitRunBuilder for %s', repo.full_fs_path)
+    if repo.tool.lower() != 'svn':
+        # Refresh commit runs
+        commit_run_ids = commit_ids
+        # Check if the CommitRuns for the repo are in a good state by checking for
+        # a CommitRunDoc that contains the last known commit. If there isn't one,
+        # the CommitRuns for this repo are in a bad state - rebuild them entirely.
+        if commit_run_ids != all_commit_ids:
+            last_commit = last_known_commit_id(all_commit_ids, new_commit_ids)
+            log.info('Last known commit id: %s', last_commit)
+            if not CommitRunDoc.m.find(dict(commit_ids=last_commit)).count():
+                log.info('CommitRun incomplete, rebuilding with all commits')
+                commit_run_ids = all_commit_ids
+        log.info('Starting CommitRunBuilder for %s', repo.full_fs_path)
+        rb = CommitRunBuilder(commit_run_ids)
+        rb.run()
+        rb.cleanup()
+        log.info('Finished CommitRunBuilder for %s', repo.full_fs_path)
 
     # Refresh trees
     # Like diffs below, pre-computing trees for SVN repos is too expensive,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 3635cbe..aabaa61 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -1,3 +1,4 @@
+import sys
 import os
 import stat
 import errno
@@ -9,6 +10,7 @@ from difflib import SequenceMatcher
 from hashlib import sha1
 from datetime import datetime
 from collections import defaultdict
+from itertools import izip
 
 import tg
 from paste.deploy.converters import asbool
@@ -28,6 +30,7 @@ from .auth import User
 from .session import repository_orm_session, project_orm_session
 from .notification import Notification
 from .repo_refresh import refresh_repo
+from .repo import CommitRunDoc, QSIZE
 from .timeline import ActivityObject
 
 log = logging.getLogger(__name__)
@@ -210,9 +213,24 @@ class Repository(Artifact, ActivityObject):
         return self._impl.compute_tree_new(commit, path)
 
     def _log(self, rev, skip, max_count):
-        ci = self.commit(rev)
-        if ci is None: return []
-        return ci.log(int(skip), int(max_count))
+        head = self.commit(rev)
+        if head is None: return
+        for oids in utils.chunked_iter(self.commitlog([head._id]), QSIZE):
+            oids = list(oids)
+            commits = dict(
+                (ci._id, ci) for ci in head.query.find(dict(
+                        _id={'$in': oids})))
+            for oid in oids:
+                if skip:
+                    skip -= 1
+                    continue
+                if max_count:
+                    max_count -= 1
+                    ci = commits[oid]
+                    ci.set_context(self)
+                    yield ci
+                else:
+                    break
 
     def init_as_clone(self, source_path, source_name, source_url, copy_hooks=False):
         self.upstream_repo.name = source_name
@@ -224,15 +242,89 @@ class Repository(Artifact, ActivityObject):
     def log(self, branch='master', offset=0, limit=10):
         return list(self._log(rev=branch, skip=offset, max_count=limit))
 
+    def commitlog(self, commit_ids, skip=0, limit=sys.maxint):
+        seen = set()
+        def _visit(commit_id):
+            if commit_id in seen: return
+            run = CommitRunDoc.m.get(commit_ids=commit_id)
+            if run is None: return
+            index = False
+            for pos, (oid, time) in enumerate(izip(run.commit_ids, run.commit_times)):
+                if oid == commit_id: index = True
+                elif not index: continue
+                seen.add(oid)
+                ci_times[oid] = time
+                if pos+1 < len(run.commit_ids):
+                    ci_parents[oid] = [ run.commit_ids[pos+1] ]
+                else:
+                    ci_parents[oid] = run.parent_commit_ids
+            for oid in run.parent_commit_ids:
+                if oid not in seen:
+                    _visit(oid)
+
+        def _gen_ids(commit_ids, skip, limit):
+            # Traverse the graph in topo order, yielding commit IDs
+            commits = set(commit_ids)
+            new_parent = None
+            while commits and limit:
+                # next commit is latest commit that's valid to log
+                if new_parent in commits:
+                    ci = new_parent
+                else:
+                    ci = max(commits, key=lambda ci:ci_times[ci])
+                commits.remove(ci)
+                if skip:
+                    skip -= 1
+                    continue
+                else:
+                    limit -= 1
+                yield ci
+                # remove this commit from its parents children and add any childless
+                # parents to the 'ready set'
+                new_parent = None
+                for oid in ci_parents.get(ci, []):
+                    children = ci_children[oid]
+                    children.discard(ci)
+                    if not children:
+                        commits.add(oid)
+                        new_parent = oid
+
+        # Load all the runs to build a commit graph
+        ci_times = {}
+        ci_parents = {}
+        ci_children = defaultdict(set)
+        log.info('Build commit graph')
+        for cid in commit_ids:
+            _visit(cid)
+        for oid, parents in ci_parents.iteritems():
+            for ci_parent in parents:
+                ci_children[ci_parent].add(oid)
+
+        return _gen_ids(commit_ids, skip, limit)
+
     def count(self, branch='master'):
         try:
             ci = self.commit(branch)
             if ci is None: return 0
-            return ci.count_revisions()
+            return self.count_revisions(ci)
         except: # pragma no cover
             log.exception('Error getting repo count')
             return 0
 
+    def count_revisions(self, ci):
+        from .repo_refresh import CommitRunBuilder
+        result = 0
+        # If there's no CommitRunDoc for this commit, the call to
+        # commitlog() below will raise a KeyError. Repair the CommitRuns for
+        # this repo by rebuilding them entirely.
+        if not CommitRunDoc.m.find(dict(commit_ids=ci._id)).count():
+            log.info('CommitRun incomplete, rebuilding with all commits')
+            rb = CommitRunBuilder(list(self.all_commit_ids()))
+            rb.run()
+            rb.cleanup()
+        for oid in self.commitlog([ci._id]): result += 1
+        return result
+
     def latest(self, branch='master'):
         if self._impl is None: return None
         try:
@@ -323,7 +415,7 @@ class Repository(Artifact, ActivityObject):
             for head in self.heads + self.branches + self.repo_tags:
                 ci = self.commit(head.object_id)
                 if ci is not None:
-                    head.count = ci.count_revisions()
+                    head.count = self.count_revisions(ci)
         finally:
             log.info('... %s ready', self)
             self.status = 'ready'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/Allura/allura/tests/model/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index 2b20b44..24b4800 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -123,15 +123,20 @@ class TestRepo(_TestWithRepo):
         assert self.repo.upstream_repo.url == 'srcurl'
         assert self.repo._impl.clone_from.called_with('srcpath')
 
-    def test_log(self):
-        ci = mock.Mock()
-        ci.log = mock.Mock(return_value=[1,2,3])
-        self.repo._impl.commit = mock.Mock(return_value=ci)
-        assert self.repo.log() == [1,2,3], self.repo.log()
+    @mock.patch.object(M.repo.CommitRunDoc.m, 'get')
+    def test_log(self, crd):
+        head = mock.Mock(_id=4)
+        commits = [mock.Mock(_id=i) for i in (1,3,2)]
+        commits.append(head)
+        head.query.find.return_value = commits
+        self.repo._impl.commit = mock.Mock(return_value=head)
+        crd.return_value = mock.Mock(commit_ids=[4, 3, 2, 1], commit_times=[4, 3, 2, 1], parent_commit_ids=[])
+        log = self.repo.log()
+        assert_equal([c._id for c in log], [4, 3, 2, 1])
 
     def test_count_revisions(self):
         ci = mock.Mock()
-        ci.count_revisions = mock.Mock(return_value=42)
+        self.repo.count_revisions = mock.Mock(return_value=42)
         self.repo._impl.commit = mock.Mock(return_value=ci)
         assert self.repo.count() == 42
 
@@ -172,13 +177,13 @@ class TestRepo(_TestWithRepo):
 
     def test_refresh(self):
         ci = mock.Mock()
-        ci.count_revisions=mock.Mock(return_value=100)
         ci.authored.name = 'Test Committer'
         ci.author_url = '/u/test-committer/'
         self.repo._impl.commit = mock.Mock(return_value=ci)
         self.repo._impl.new_commits = mock.Mock(return_value=['foo%d' % i for i in range(100) ])
         self.repo._impl.all_commit_ids = mock.Mock(return_value=['foo%d' % i for i in range(100) ])
         self.repo.symbolics_for_commit = mock.Mock(return_value=[['master', 'branch'], []])
+        self.repo.count_revisions=mock.Mock(return_value=100)
         def refresh_commit_info(oid, seen, lazy=False):
             M.repo.CommitDoc(dict(
                     authored=dict(
@@ -213,9 +218,9 @@ class TestRepo(_TestWithRepo):
 
     def test_refresh_private(self):
         ci = mock.Mock()
-        ci.count_revisions=mock.Mock(return_value=100)
         self.repo._impl.commit = mock.Mock(return_value=ci)
         self.repo._impl.new_commits = mock.Mock(return_value=['foo%d' % i for i in range(100) ])
+        self.repo.count_revisions=mock.Mock(return_value=100)
         def set_heads():
             self.repo.heads = [ ming.base.Object(name='head', object_id='foo0', count=100) ]
         self.repo._impl.refresh_heads = mock.Mock(side_effect=set_heads)
@@ -348,18 +353,11 @@ class TestCommit(_TestWithRepo):
         x = self.ci.get_path('a/a')
         assert isinstance(x, M.repo.Tree)
 
-    def test_log(self):
-        rb = M.repo_refresh.CommitRunBuilder(['foo'])
-        rb.run()
-        rb.cleanup()
-        commits = self.ci.log(0, 100)
-        assert commits[0]._id == 'foo'
-
     def test_count_revisions(self):
         rb = M.repo_refresh.CommitRunBuilder(['foo'])
         rb.run()
         rb.cleanup()
-        assert self.ci.count_revisions() == 1
+        assert self.repo.count_revisions(self.ci) == 1
 
     def test_compute_diffs(self):
         self.repo._impl.commit = mock.Mock(return_value=self.ci)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index fe878dc..684c8d6 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -60,13 +60,12 @@ class TestNewGit(unittest.TestCase):
         assert self.rev.url() == (
             '/p/test/src-git/ci/'
             '1e146e67985dcd71c74de79613719bef7bddca4a/')
-        all_cis = self.rev.log(0, 1000)
+        all_cis = self.repo.log(self.rev._id, 0, 1000)
         assert len(all_cis) == 4
-        assert self.rev.log(1,1000) == all_cis[1:]
-        assert self.rev.log(0,3) == all_cis[:3]
-        assert self.rev.log(1,2) == all_cis[1:3]
+        assert self.repo.log(self.rev._id, 1,1000) == all_cis[1:]
+        assert self.repo.log(self.rev._id, 0,3) == all_cis[:3]
+        assert self.repo.log(self.rev._id, 1,2) == all_cis[1:3]
         for ci in all_cis:
-            ci.count_revisions()
             ci.context()
         self.rev.tree.ls()
         # print self.rev.tree.readme()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/ForgeHg/forgehg/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeHg/forgehg/tests/model/test_repository.py b/ForgeHg/forgehg/tests/model/test_repository.py
index 488c142..1193dcb 100644
--- a/ForgeHg/forgehg/tests/model/test_repository.py
+++ b/ForgeHg/forgehg/tests/model/test_repository.py
@@ -61,13 +61,12 @@ class TestNewRepo(unittest.TestCase):
         assert self.rev.url() == (
             '/p/test/src-hg/ci/'
             '5a0a993efa9bce7d1983344261393e841fcfd65d/')
-        all_cis = self.rev.log(0, 1000)
+        all_cis = self.repo.log(self.rev._id, 0, 1000)
         assert len(all_cis) == 6
-        assert self.rev.log(1,1000) == all_cis[1:]
-        assert self.rev.log(0,3) == all_cis[:3]
-        assert self.rev.log(1,2) == all_cis[1:3]
+        assert self.repo.log(self.rev._id, 1,1000) == all_cis[1:]
+        assert self.repo.log(self.rev._id, 0,3) == all_cis[:3]
+        assert self.repo.log(self.rev._id, 1,2) == all_cis[1:3]
         for ci in all_cis:
-            ci.count_revisions()
             ci.context()
         self.rev.tree.ls()
         assert self.rev.tree.readme() == (

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index 5e6cb81..1b84553 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -1,3 +1,4 @@
+import sys
 import re
 import os
 import shutil
@@ -42,11 +43,6 @@ class Repository(M.Repository):
     def _impl(self):
         return SVNImplementation(self)
 
-    def _log(self, rev, skip, max_count):
-        ci = self.commit(rev)
-        if ci is None: return []
-        return ci.log(int(skip), int(max_count))
-
     def clone_command(self, category, username=''):
         '''Return a string suitable for copy/paste that would clone this repo locally
            category is one of 'ro' (read-only), 'rw' (read/write), or 'https' (read/write via https)
@@ -64,9 +60,26 @@ class Repository(M.Repository):
     def count(self, *args, **kwargs):
         return super(Repository, self).count(None)
 
-    def log(self, branch=None, offset=0, limit=10):
+    def count_revisions(self, ci):
+        # since SVN histories are inherently linear and the commit _id
+        # contains the revision, just parse it out from there
+        return int(ci._id.split(':')[1])
+
+    def log(self, branch='HEAD', offset=0, limit=10):
         return list(self._log(rev=branch, skip=offset, max_count=limit))
 
+    def commitlog(self, commit_ids, skip=0, limit=sys.maxint):
+        ci_id = commit_ids[0]
+        if skip > 0:
+            rid, rev = ci_id.split(':')
+            rev = int(rev) - skip
+            ci_id = '%s:%s' % (rid, rev)
+        ci = self._impl.commit(ci_id)
+        while ci is not None and limit > 0:
+            yield ci._id
+            limit -= 1
+            ci = ci.parent()
+
     def latest(self, branch=None):
         if self._impl is None: return None
         if not self.heads: return None

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f88173a6/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 44b18b9..94912f9 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -3,6 +3,7 @@ import shutil
 import unittest
 import pkg_resources
 
+import mock
 from ming.orm import ThreadLocalORMSession
 
 from alluratest.controller import setup_basic_test, setup_global_objects
@@ -53,13 +54,12 @@ class TestNewRepo(unittest.TestCase):
         assert self.rev.symbolic_ids == ([], [])
         assert self.rev.url() == (
             '/p/test/src/5/')
-        all_cis = self.rev.log(0, 1000)
+        all_cis = self.repo.log(self.rev._id, 0, 1000)
         assert len(all_cis) == 5
-        assert self.rev.log(1,1000) == all_cis[1:]
-        assert self.rev.log(0,3) == all_cis[:3]
-        assert self.rev.log(1,2) == all_cis[1:3]
+        assert self.repo.log(self.rev._id, 1,1000) == all_cis[1:]
+        assert self.repo.log(self.rev._id, 0,3) == all_cis[:3]
+        assert self.repo.log(self.rev._id, 1,2) == all_cis[1:3]
         for ci in all_cis:
-            ci.count_revisions()
             ci.context()
         self.rev.tree.ls()
         assert self.rev.tree.readme() == (
@@ -232,6 +232,10 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         assert svn_path_exists("file://%s" % repo_path)
         assert not svn_path_exists("file://%s/badpath" % repo_path)
 
+    def test_count_revisions(self):
+        ci = mock.Mock(_id='deadbeef:100')
+        self.assertEqual(self.repo.count_revisions(ci), 100)
+
 
 class TestSVNRev(unittest.TestCase):