dulwich-users team mailing list archive
-
dulwich-users team
-
Mailing list archive
-
Message #00781
[PATCH 1/6] Graft Tests
https://git.wiki.kernel.org/index.php/GraftPoint
GraftPoints are existing Commits that have their parents "rewritten"
To support graftpoints:
1) A new object GraftedCommit is needed to manage Commit parents
2) ObjectStores must be able to return GraftedCommit objects
3) Repos must be able to manage its own graftpoints
---
dulwich/tests/__init__.py | 1 +
dulwich/tests/test_grafts.py | 313 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 314 insertions(+), 0 deletions(-)
create mode 100644 dulwich/tests/test_grafts.py
diff --git a/dulwich/tests/__init__.py b/dulwich/tests/__init__.py
index c9b9390..2fb25e7 100644
--- a/dulwich/tests/__init__.py
+++ b/dulwich/tests/__init__.py
@@ -117,6 +117,7 @@ def self_test_suite():
'diff_tree',
'fastexport',
'file',
+ 'grafts',
'hooks',
'index',
'lru_cache',
diff --git a/dulwich/tests/test_grafts.py b/dulwich/tests/test_grafts.py
new file mode 100644
index 0000000..c2b37c6
--- /dev/null
+++ b/dulwich/tests/test_grafts.py
@@ -0,0 +1,313 @@
+# test_grafts.py -- Tests for graftpoints
+#
+# 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
+# or (at your option) a later version of the License.
+#
+# 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 graftpoints."""
+
+import os
+import tempfile
+import shutil
+import warnings
+
+from dulwich.errors import ObjectFormatException
+from dulwich.tests import TestCase
+from dulwich.objects import (
+ Commit,
+ GraftedCommit,
+ Tree,
+)
+from dulwich.object_store import (
+ MemoryObjectStore,
+)
+from dulwich.repo import (
+ MemoryRepo,
+ Repo,
+)
+from dulwich.tests.utils import (
+ make_commit,
+ setup_warning_catcher
+)
+
+
+default_committer = 'James Westby <jw+debian@xxxxxxxxxxxxxxx> 1174773719 +0000'
+
+
+class GraftedCommitTests(TestCase):
+
+ def setUp(self):
+ self._gc = GraftedCommit(commit=self.make_commit())
+
+ def make_commit(self):
+ attrs = {'tree': 'd80c186a03f423a81b39df39dc87fd269736ca86',
+ 'parents': ['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
+ '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
+ 'author': 'James Westby <jw+debian@xxxxxxxxxxxxxxx>',
+ 'committer': 'James Westby <jw+debian@xxxxxxxxxxxxxxx>',
+ 'commit_time': 1174773719,
+ 'author_time': 1174773719,
+ 'commit_timezone': 0,
+ 'author_timezone': 0,
+ 'message': 'Merge ../b\n'}
+ return make_commit(**attrs)
+
+ def test_graft_sha_equality(self):
+ c = self.make_commit()
+ gc = GraftedCommit(c, [])
+ self.assertEqual(gc.sha, c.sha)
+
+ gc = self._gc
+ gc.fake_parents = []
+ self.assertEqual(gc.sha, c.sha)
+
+ def test_graft_inherited_from_commit(self):
+ gc = self._gc
+ self.assertTrue(isinstance(gc, Commit))
+ self.assertTrue(issubclass(GraftedCommit, Commit))
+
+ def test_graft_serialization(self):
+ c = self.make_commit()
+ gc = self._gc
+ gc.fake_parents = []
+
+ self.assertEqual(gc.as_raw_string(), c.as_raw_string())
+
+ def test_graft_real_parents_property(self):
+ gc = self._gc
+ gc.real_parents = []
+ self.assertEqual([], gc.real_parents)
+
+ def test_graft_fake_parents_property(self):
+ gc = self._gc
+ gc.fake_parents = []
+ self.assertEqual([], gc.fake_parents)
+
+ def test_graft_parents_property_no_fake(self):
+ gc = self._gc
+ gc.parents = []
+ self.assertEqual([], gc.parents)
+
+ def test_graft_parents_property_existing_fake(self):
+ gc = self._gc
+ gc.fake_parents = ['4cffe90e0a41ad3f5190079d7c8f036bde29cbe6']
+ self.assertEqual(['4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
+ gc.fake_parents)
+
+ gc.parents = []
+ self.assertEqual([], gc.parents)
+ self.assertEqual([], gc.fake_parents)
+
+ def test_graft_no_parents(self):
+ gc = self._gc
+ gc.fake_parents = []
+
+ self.assertEqual([], gc.parents)
+ self.assertEqual(['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
+ '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
+ gc.real_parents)
+
+ def test_graft_fake_parent(self):
+ gc = self._gc
+ gc.fake_parents = ['0d89f20333fbb1d2f3a94da77f4981373d8f4310']
+
+ self.assertEqual(
+ ['0d89f20333fbb1d2f3a94da77f4981373d8f4310'],
+ gc.parents)
+ self.assertEqual(['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
+ '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
+ gc.real_parents)
+
+ def test_graft_check(self):
+ gc = self._gc
+
+ gc.fake_parents = ['0d89f20333fbb1d2f3a94da77f4981373d8f4310']
+ gc.check()
+
+ gc.fake_parents = ['asdfasdf']
+ self.assertRaises(ObjectFormatException, gc.check)
+
+
+class GraftsInObjectStore(TestCase):
+
+ def setUp(self):
+ store = self._store = MemoryObjectStore()
+
+ commit = self.make_commit()
+ store.add_object(commit)
+ self._commit_sha = commit.id
+
+ def make_commit(self, **kwargs):
+ attrs = {'tree': 'd80c186a03f423a81b39df39dc87fd269736ca86',
+ 'parents': ['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
+ '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
+ 'author': 'James Westby <jw+debian@xxxxxxxxxxxxxxx>',
+ 'committer': 'James Westby <jw+debian@xxxxxxxxxxxxxxx>',
+ 'commit_time': 1174773719,
+ 'author_time': 1174773719,
+ 'commit_timezone': 0,
+ 'author_timezone': 0,
+ 'message': 'Merge ../b\n'}
+ attrs.update(kwargs)
+ return make_commit(**attrs)
+
+ def test_graft_property(self):
+ store = self._store
+
+ self.assertEqual({}, store.grafts)
+
+ store.grafts = {self._commit_sha: []}
+
+ self.assertEqual({self._commit_sha: []}, store.grafts)
+
+ def test_getitem(self):
+ store = self._store
+ store.grafts = {self._commit_sha: []}
+ gc = store[self._commit_sha]
+ self.assertTrue(isinstance(gc, GraftedCommit))
+ self.assertEqual([], gc.parents)
+
+
+class GraftsInRepositoryBase(object):
+
+ def tearDown(self):
+ super(GraftsInRepositoryBase, self).tearDown()
+
+ def test_no_grafts(self):
+ r = self._repo
+ r._put_named_file(os.path.join('info', 'grafts'), '')
+
+ shas = [e.commit.id for e in r.get_walker()]
+ self.assertEqual(shas, self._shas[::-1])
+
+ def test_no_parents_graft(self):
+ r = self._repo
+ r._put_named_file(os.path.join('info', 'grafts'), r.head())
+
+ self.assertEqual([e.commit.id for e in r.get_walker()],
+ [r.head()])
+
+ def test_existing_parent_graft(self):
+ r = self._repo
+ r._put_named_file(
+ os.path.join('info', 'grafts'),
+ "%s %s" % (self._shas[-1], self._shas[0]))
+
+ self.assertEqual([e.commit.id for e in r.get_walker()],
+ [self._shas[-1], self._shas[0]])
+
+ def test_add_no_parents_graft(self):
+ r = self._repo
+ r.add_grafts({r.head(): []})
+
+ self.assertEqual([e.commit.id for e in r.get_walker()],
+ [r.head()])
+
+ def test_add_existing_parent_graft(self):
+ r = self._repo
+ r.add_grafts({self._shas[-1]: [self._shas[0]]})
+
+ self.assertEqual([e.commit.id for e in r.get_walker()],
+ [self._shas[-1], self._shas[0]])
+
+ def test_remove_graft(self):
+ r = self._repo
+ r.add_grafts({r.head(): []})
+ r.remove_grafts([r.head()])
+
+ self.assertEqual([e.commit.id for e in r.get_walker()],
+ self._shas[::-1])
+
+ def test_seralize_grafts(self):
+ r = self._repo
+ r.add_grafts({self._shas[-1]: [self._shas[0]]})
+
+ grafts = r.serialize_grafts()
+ self.assertEqual(["%s %s" % (self._shas[-1], self._shas[0])],
+ grafts.splitlines())
+
+ def test_object_store_skip_invalid_parents(self):
+ r = self._repo
+
+ warnings.simplefilter("always", UserWarning)
+ warnings_list = setup_warning_catcher()
+
+ r.add_grafts({self._shas[-1]: ['1' * 40]})
+
+ self.assertEqual(len(warnings_list), 1)
+ self.assertIsInstance(warnings_list[-1], UserWarning)
+
+ shas = [e.commit.id for e in r.get_walker()]
+ self.assertEqual(shas, self._shas[::-1])
+
+
+class GraftsInRepoTests(GraftsInRepositoryBase, TestCase):
+
+ def setUp(self):
+ super(GraftsInRepoTests, self).setUp()
+ self._repo_dir = os.path.join(tempfile.mkdtemp())
+ r = self._repo = Repo.init(self._repo_dir)
+ self.addCleanup(shutil.rmtree, self._repo_dir)
+
+ self._shas = []
+
+ commit_kwargs = {
+ 'committer': 'Test Committer <test@xxxxxxxxxxxx>',
+ 'author': 'Test Author <test@xxxxxxxxxxxx>',
+ 'commit_timestamp': 12395,
+ 'commit_timezone': 0,
+ 'author_timestamp': 12395,
+ 'author_timezone': 0,
+ }
+
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
+
+ def test_init_with_empty_info_grafts(self):
+ r = self._repo
+ r._put_named_file(os.path.join('info', 'grafts'), r.head())
+
+ r = Repo(self._repo_dir)
+
+
+class GraftsInMemoryRepoTests(GraftsInRepositoryBase, TestCase):
+
+ def setUp(self):
+ super(GraftsInMemoryRepoTests, self).setUp()
+ r = self._repo = MemoryRepo()
+
+ self._shas = []
+
+ tree = Tree()
+
+ commit_kwargs = {
+ 'committer': 'Test Committer <test@xxxxxxxxxxxx>',
+ 'author': 'Test Author <test@xxxxxxxxxxxx>',
+ 'commit_timestamp': 12395,
+ 'commit_timezone': 0,
+ 'author_timestamp': 12395,
+ 'author_timezone': 0,
+ 'tree': tree.id
+ }
+
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
+ self._shas.append(r.do_commit(
+ 'empty commit', **commit_kwargs))
--
1.7.1
References