2
0

test_fastexport.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # test_fastexport.py -- Fast export/import functionality
  2. # Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
  3. #
  4. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  5. # General Public License as public by the Free Software Foundation; version 2.0
  6. # or (at your option) any later version. You can redistribute it and/or
  7. # modify it under the terms of either of these two licenses.
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. # You should have received a copy of the licenses; if not, see
  16. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  17. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  18. # License, Version 2.0.
  19. #
  20. from io import BytesIO
  21. import stat
  22. from dulwich.object_store import (
  23. MemoryObjectStore,
  24. )
  25. from dulwich.objects import (
  26. Blob,
  27. Commit,
  28. Tree,
  29. )
  30. from dulwich.repo import (
  31. MemoryRepo,
  32. )
  33. from dulwich.tests import (
  34. SkipTest,
  35. TestCase,
  36. )
  37. from dulwich.tests.utils import (
  38. build_commit_graph,
  39. )
  40. class GitFastExporterTests(TestCase):
  41. """Tests for the GitFastExporter tests."""
  42. def setUp(self):
  43. super(GitFastExporterTests, self).setUp()
  44. self.store = MemoryObjectStore()
  45. self.stream = BytesIO()
  46. try:
  47. from dulwich.fastexport import GitFastExporter
  48. except ImportError:
  49. raise SkipTest("python-fastimport not available")
  50. self.fastexporter = GitFastExporter(self.stream, self.store)
  51. def test_emit_blob(self):
  52. b = Blob()
  53. b.data = b"fooBAR"
  54. self.fastexporter.emit_blob(b)
  55. self.assertEqual(b'blob\nmark :1\ndata 6\nfooBAR\n',
  56. self.stream.getvalue())
  57. def test_emit_commit(self):
  58. b = Blob()
  59. b.data = b"FOO"
  60. t = Tree()
  61. t.add(b"foo", stat.S_IFREG | 0o644, b.id)
  62. c = Commit()
  63. c.committer = c.author = b"Jelmer <jelmer@host>"
  64. c.author_time = c.commit_time = 1271345553
  65. c.author_timezone = c.commit_timezone = 0
  66. c.message = b"msg"
  67. c.tree = t.id
  68. self.store.add_objects([(b, None), (t, None), (c, None)])
  69. self.fastexporter.emit_commit(c, b"refs/heads/master")
  70. self.assertEqual(b"""blob
  71. mark :1
  72. data 3
  73. FOO
  74. commit refs/heads/master
  75. mark :2
  76. author Jelmer <jelmer@host> 1271345553 +0000
  77. committer Jelmer <jelmer@host> 1271345553 +0000
  78. data 3
  79. msg
  80. M 644 :1 foo
  81. """, self.stream.getvalue())
  82. class GitImportProcessorTests(TestCase):
  83. """Tests for the GitImportProcessor tests."""
  84. def setUp(self):
  85. super(GitImportProcessorTests, self).setUp()
  86. self.repo = MemoryRepo()
  87. try:
  88. from dulwich.fastexport import GitImportProcessor
  89. except ImportError:
  90. raise SkipTest("python-fastimport not available")
  91. self.processor = GitImportProcessor(self.repo)
  92. def test_reset_handler(self):
  93. from fastimport import commands
  94. [c1] = build_commit_graph(self.repo.object_store, [[1]])
  95. cmd = commands.ResetCommand(b"refs/heads/foo", c1.id)
  96. self.processor.reset_handler(cmd)
  97. self.assertEqual(c1.id, self.repo.get_refs()[b"refs/heads/foo"])
  98. def test_commit_handler(self):
  99. from fastimport import commands
  100. cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr",
  101. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  102. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  103. b"FOO", None, [], [])
  104. self.processor.commit_handler(cmd)
  105. commit = self.repo[self.processor.last_commit]
  106. self.assertEqual(b"Jelmer <jelmer@samba.org>", commit.author)
  107. self.assertEqual(b"Jelmer <jelmer@samba.org>", commit.committer)
  108. self.assertEqual(b"FOO", commit.message)
  109. self.assertEqual([], commit.parents)
  110. self.assertEqual(432432432.0, commit.commit_time)
  111. self.assertEqual(432432432.0, commit.author_time)
  112. self.assertEqual(3600, commit.commit_timezone)
  113. self.assertEqual(3600, commit.author_timezone)
  114. self.assertEqual(commit, self.repo[b"refs/heads/foo"])
  115. def test_import_stream(self):
  116. markers = self.processor.import_stream(BytesIO(b"""blob
  117. mark :1
  118. data 11
  119. text for a
  120. commit refs/heads/master
  121. mark :2
  122. committer Joe Foo <joe@foo.com> 1288287382 +0000
  123. data 20
  124. <The commit message>
  125. M 100644 :1 a
  126. """))
  127. self.assertEqual(2, len(markers))
  128. self.assertTrue(isinstance(self.repo[markers[b"1"]], Blob))
  129. self.assertTrue(isinstance(self.repo[markers[b"2"]], Commit))
  130. def test_file_add(self):
  131. from fastimport import commands
  132. cmd = commands.BlobCommand(b"23", b"data")
  133. self.processor.blob_handler(cmd)
  134. cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr",
  135. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  136. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  137. b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)])
  138. self.processor.commit_handler(cmd)
  139. commit = self.repo[self.processor.last_commit]
  140. self.assertEqual([
  141. (b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172')],
  142. self.repo[commit.tree].items())
  143. def simple_commit(self):
  144. from fastimport import commands
  145. cmd = commands.BlobCommand(b"23", b"data")
  146. self.processor.blob_handler(cmd)
  147. cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr",
  148. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  149. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  150. b"FOO", None, [], [commands.FileModifyCommand(b"path", 0o100644, b":23", None)])
  151. self.processor.commit_handler(cmd)
  152. commit = self.repo[self.processor.last_commit]
  153. return commit
  154. def make_file_commit(self, file_cmds):
  155. """Create a trivial commit with the specified file commands.
  156. :param file_cmds: File commands to run.
  157. :return: The created commit object
  158. """
  159. from fastimport import commands
  160. cmd = commands.CommitCommand(b"refs/heads/foo", b"mrkr",
  161. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  162. (b"Jelmer", b"jelmer@samba.org", 432432432.0, 3600),
  163. b"FOO", None, [], file_cmds)
  164. self.processor.commit_handler(cmd)
  165. return self.repo[self.processor.last_commit]
  166. def test_file_copy(self):
  167. from fastimport import commands
  168. self.simple_commit()
  169. commit = self.make_file_commit([commands.FileCopyCommand(b"path", b"new_path")])
  170. self.assertEqual([
  171. (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'),
  172. (b'path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'),
  173. ], self.repo[commit.tree].items())
  174. def test_file_move(self):
  175. from fastimport import commands
  176. self.simple_commit()
  177. commit = self.make_file_commit([commands.FileRenameCommand(b"path", b"new_path")])
  178. self.assertEqual([
  179. (b'new_path', 0o100644, b'6320cd248dd8aeaab759d5871f8781b5c0505172'),
  180. ], self.repo[commit.tree].items())
  181. def test_file_delete(self):
  182. from fastimport import commands
  183. self.simple_commit()
  184. commit = self.make_file_commit([commands.FileDeleteCommand(b"path")])
  185. self.assertEqual([], self.repo[commit.tree].items())
  186. def test_file_deleteall(self):
  187. from fastimport import commands
  188. self.simple_commit()
  189. commit = self.make_file_commit([commands.FileDeleteAllCommand()])
  190. self.assertEqual([], self.repo[commit.tree].items())