← Back to team overview

dulwich-users team mailing list archive

[PATCH 01/34] tests/utils: Function for quickly building commit graphs.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: I685e427e211be19733f2aa8c30456af039d244e0
---
 NEWS                            |    3 ++
 dulwich/tests/test_diff_tree.py |    4 +--
 dulwich/tests/test_utils.py     |   61 +++++++++++++++++++++++++++++++++++++++
 dulwich/tests/utils.py          |   55 +++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 3 deletions(-)
 create mode 100644 dulwich/tests/test_utils.py

diff --git a/NEWS b/NEWS
index 6c2fc29..264bbd5 100644
--- a/NEWS
+++ b/NEWS
@@ -72,6 +72,9 @@
   * Add a new build_pack test utility for building packs from a simple spec.
     (Dave Borowitz)
 
+  * Add a new build_commit_graph test utility for building commits from a
+    simple spec. (Dave Borowitz)
+
 0.7.1	2011-04-12
 
  BUG FIXES
diff --git a/dulwich/tests/test_diff_tree.py b/dulwich/tests/test_diff_tree.py
index 741d4cd..d5fa5c4 100644
--- a/dulwich/tests/test_diff_tree.py
+++ b/dulwich/tests/test_diff_tree.py
@@ -54,14 +54,12 @@ from dulwich.tests import (
     TestCase,
     )
 from dulwich.tests.utils import (
+    F,
     make_object,
     functest_builder,
     ext_functest_builder,
     )
 
-# Shorthand mode for Files.
-F = 0100644
-
 
 class DiffTestCase(TestCase):
 
diff --git a/dulwich/tests/test_utils.py b/dulwich/tests/test_utils.py
new file mode 100644
index 0000000..b96928d
--- /dev/null
+++ b/dulwich/tests/test_utils.py
@@ -0,0 +1,61 @@
+# test_utils.py -- Tests for git test utilities.
+# Copyright (C) 2010 Google, Inc.
+#
+# 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 git test utilities."""
+
+from dulwich.object_store import (
+    MemoryObjectStore,
+    )
+from dulwich.objects import (
+    Blob,
+    )
+from dulwich.tests import (
+    TestCase,
+    )
+from utils import (
+    make_object,
+    build_commit_graph,
+    )
+
+
+class BuildCommitGraphTest(TestCase):
+
+    def setUp(self):
+        self.store = MemoryObjectStore()
+
+    def test_linear(self):
+        c1, c2 = build_commit_graph(self.store, [[1], [2, 1]])
+        for obj_id in [c1.id, c2.id, c1.tree, c2.tree]:
+            self.assertTrue(obj_id in self.store)
+        self.assertEqual([], c1.parents)
+        self.assertEqual([c1.id], c2.parents)
+        self.assertEqual(c1.tree, c2.tree)
+        self.assertEqual([], list(self.store[c1.tree].iteritems()))
+        self.assertTrue(c2.commit_time > c1.commit_time)
+
+    def test_merge(self):
+        c1, c2, c3, c4 = build_commit_graph(self.store,
+                                            [[1], [2, 1], [3, 1], [4, 2, 3]])
+        self.assertEqual([c2.id, c3.id], c4.parents)
+        self.assertTrue(c4.commit_time > c2.commit_time)
+        self.assertTrue(c4.commit_time > c3.commit_time)
+
+    def test_missing_parent(self):
+        self.assertRaises(ValueError, build_commit_graph, self.store,
+                          [[1], [3, 2], [2, 1]])
diff --git a/dulwich/tests/utils.py b/dulwich/tests/utils.py
index 7de763d..a2cf9de 100644
--- a/dulwich/tests/utils.py
+++ b/dulwich/tests/utils.py
@@ -31,6 +31,7 @@ import types
 from dulwich.objects import (
     FixedSha,
     Commit,
+    Tree,
     )
 from dulwich.pack import (
     OFS_DELTA,
@@ -47,6 +48,9 @@ from dulwich.tests import (
     TestSkipped,
     )
 
+# Plain files are very frequently used in tests, so let the mode be very short.
+F = 0100644  # Shorthand mode for Files.
+
 
 def open_repo(name):
     """Open a copy of a repo in a temporary directory.
@@ -230,3 +234,54 @@ def build_pack(f, objects_spec, store=None):
     sf.write_sha()
     f.seek(0)
     return expected
+
+
+def build_commit_graph(object_store, commit_spec):
+    """Build a commit graph from a concise specification.
+
+    Sample usage:
+    >>> c1, c2, c3 = build_commit_graph(store, [[1], [2, 1], [3, 1, 2]])
+    >>> store[store[c3].parents[0]] == c1
+    True
+    >>> store[store[c3].parents[1]] == c2
+    True
+
+    If not otherwise specified, commits will refer to the empty tree and have
+    commit times increasing in the same order as the commit spec.
+
+    :param object_store: An ObjectStore to commit objects to.
+    :param commit_spec: An iterable of iterables of ints defining the commit
+        graph. Each entry defines one commit, and entries must be in topological
+        order. The first element of each entry is a commit number, and the
+        remaining elements are its parents. The commit numbers are only
+        meaningful for the call to make_commits; since real commit objects are
+        created, they will get created with real, opaque SHAs.
+    :return: The list of commit objects created.
+    :raise ValueError: If an undefined commit identifier is listed as a parent.
+    """
+    commit_time = 0
+    nums = {}
+    commits = []
+
+    for commit in commit_spec:
+        commit_num = commit[0]
+        try:
+            parent_ids = [nums[pn] for pn in commit[1:]]
+        except KeyError, e:
+            missing_parent, = e.args
+            raise ValueError('Unknown parent %i' % missing_parent)
+
+        tree = Tree()
+        commit_obj = make_commit(
+          message=('Commit %i' % commit_num),
+          parents=parent_ids,
+          tree=tree.id,
+          commit_time=commit_time)
+
+        commit_time += 1
+        nums[commit_num] = commit_obj.id
+        object_store.add_object(commit_obj)
+        object_store.add_object(tree)
+        commits.append(commit_obj)
+
+    return commits
-- 
1.7.3.1



References