test_porcelain.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. # test_porcelain.py -- porcelain tests
  2. # Copyright (C) 2013 Jelmer Vernooij <jelmer@samba.org>
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; version 2
  7. # of the License or (at your option) a later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. # MA 02110-1301, USA.
  18. """Tests for dulwich.porcelain."""
  19. from cStringIO import StringIO
  20. import os
  21. import shutil
  22. import tarfile
  23. import tempfile
  24. from dulwich import porcelain
  25. from dulwich.objects import (
  26. Blob,
  27. Tree,
  28. )
  29. from dulwich.repo import Repo
  30. from dulwich.tests import (
  31. TestCase,
  32. )
  33. from dulwich.tests.utils import (
  34. build_commit_graph,
  35. make_object,
  36. )
  37. class PorcelainTestCase(TestCase):
  38. def setUp(self):
  39. super(TestCase, self).setUp()
  40. repo_dir = tempfile.mkdtemp()
  41. self.addCleanup(shutil.rmtree, repo_dir)
  42. self.repo = Repo.init(repo_dir)
  43. class ArchiveTests(PorcelainTestCase):
  44. """Tests for the archive command."""
  45. def test_simple(self):
  46. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1], [3, 1, 2]])
  47. self.repo.refs["refs/heads/master"] = c3.id
  48. out = StringIO()
  49. err = StringIO()
  50. porcelain.archive(self.repo.path, "refs/heads/master", outstream=out,
  51. errstream=err)
  52. self.assertEquals("", err.getvalue())
  53. tf = tarfile.TarFile(fileobj=out)
  54. self.addCleanup(tf.close)
  55. self.assertEquals([], tf.getnames())
  56. class UpdateServerInfoTests(PorcelainTestCase):
  57. def test_simple(self):
  58. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  59. [3, 1, 2]])
  60. self.repo.refs["refs/heads/foo"] = c3.id
  61. porcelain.update_server_info(self.repo.path)
  62. self.assertTrue(os.path.exists(os.path.join(self.repo.controldir(),
  63. 'info', 'refs')))
  64. class CommitTests(PorcelainTestCase):
  65. def test_custom_author(self):
  66. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  67. [3, 1, 2]])
  68. self.repo.refs["refs/heads/foo"] = c3.id
  69. sha = porcelain.commit(self.repo.path, message="Some message",
  70. author="Joe <joe@example.com>", committer="Bob <bob@example.com>")
  71. self.assertTrue(type(sha) is str)
  72. self.assertEquals(len(sha), 40)
  73. class CloneTests(PorcelainTestCase):
  74. def test_simple_local(self):
  75. f1_1 = make_object(Blob, data='f1')
  76. commit_spec = [[1], [2, 1], [3, 1, 2]]
  77. trees = {1: [('f1', f1_1), ('f2', f1_1)],
  78. 2: [('f1', f1_1), ('f2', f1_1)],
  79. 3: [('f1', f1_1), ('f2', f1_1)], }
  80. c1, c2, c3 = build_commit_graph(self.repo.object_store,
  81. commit_spec, trees)
  82. self.repo.refs["refs/heads/master"] = c3.id
  83. target_path = tempfile.mkdtemp()
  84. outstream = StringIO()
  85. self.addCleanup(shutil.rmtree, target_path)
  86. r = porcelain.clone(self.repo.path, target_path,
  87. checkout=False, outstream=outstream)
  88. self.assertEquals(r.path, target_path)
  89. self.assertEquals(Repo(target_path).head(), c3.id)
  90. self.assertTrue('f1' not in os.listdir(target_path))
  91. self.assertTrue('f2' not in os.listdir(target_path))
  92. def test_simple_local_with_checkout(self):
  93. f1_1 = make_object(Blob, data='f1')
  94. commit_spec = [[1], [2, 1], [3, 1, 2]]
  95. trees = {1: [('f1', f1_1), ('f2', f1_1)],
  96. 2: [('f1', f1_1), ('f2', f1_1)],
  97. 3: [('f1', f1_1), ('f2', f1_1)], }
  98. c1, c2, c3 = build_commit_graph(self.repo.object_store,
  99. commit_spec, trees)
  100. self.repo.refs["refs/heads/master"] = c3.id
  101. target_path = tempfile.mkdtemp()
  102. outstream = StringIO()
  103. self.addCleanup(shutil.rmtree, target_path)
  104. r = porcelain.clone(self.repo.path, target_path,
  105. checkout=True, outstream=outstream)
  106. self.assertEquals(r.path, target_path)
  107. self.assertEquals(Repo(target_path).head(), c3.id)
  108. self.assertTrue('f1' in os.listdir(target_path))
  109. self.assertTrue('f2' in os.listdir(target_path))
  110. def test_bare_local_with_checkout(self):
  111. f1_1 = make_object(Blob, data='f1')
  112. commit_spec = [[1], [2, 1], [3, 1, 2]]
  113. trees = {1: [('f1', f1_1), ('f2', f1_1)],
  114. 2: [('f1', f1_1), ('f2', f1_1)],
  115. 3: [('f1', f1_1), ('f2', f1_1)], }
  116. c1, c2, c3 = build_commit_graph(self.repo.object_store,
  117. commit_spec, trees)
  118. self.repo.refs["refs/heads/master"] = c3.id
  119. target_path = tempfile.mkdtemp()
  120. outstream = StringIO()
  121. self.addCleanup(shutil.rmtree, target_path)
  122. r = porcelain.clone(self.repo.path, target_path,
  123. bare=True, outstream=outstream)
  124. self.assertEquals(r.path, target_path)
  125. self.assertEquals(Repo(target_path).head(), c3.id)
  126. self.assertFalse('f1' in os.listdir(target_path))
  127. self.assertFalse('f2' in os.listdir(target_path))
  128. def test_no_checkout_with_bare(self):
  129. f1_1 = make_object(Blob, data='f1')
  130. commit_spec = [[1]]
  131. trees = {1: [('f1', f1_1), ('f2', f1_1)]}
  132. (c1, ) = build_commit_graph(self.repo.object_store, commit_spec, trees)
  133. self.repo.refs["refs/heads/master"] = c1.id
  134. target_path = tempfile.mkdtemp()
  135. outstream = StringIO()
  136. self.addCleanup(shutil.rmtree, target_path)
  137. self.assertRaises(ValueError, porcelain.clone, self.repo.path,
  138. target_path, checkout=True, bare=True, outstream=outstream)
  139. class InitTests(TestCase):
  140. def test_non_bare(self):
  141. repo_dir = tempfile.mkdtemp()
  142. self.addCleanup(shutil.rmtree, repo_dir)
  143. porcelain.init(repo_dir)
  144. def test_bare(self):
  145. repo_dir = tempfile.mkdtemp()
  146. self.addCleanup(shutil.rmtree, repo_dir)
  147. porcelain.init(repo_dir, bare=True)
  148. class AddTests(PorcelainTestCase):
  149. def test_add_file(self):
  150. f = open(os.path.join(self.repo.path, 'foo'), 'w')
  151. try:
  152. f.write("BAR")
  153. finally:
  154. f.close()
  155. porcelain.add(self.repo.path, paths=["foo"])
  156. class RemoveTests(PorcelainTestCase):
  157. def test_remove_file(self):
  158. f = open(os.path.join(self.repo.path, 'foo'), 'w')
  159. try:
  160. f.write("BAR")
  161. finally:
  162. f.close()
  163. porcelain.add(self.repo.path, paths=["foo"])
  164. porcelain.rm(self.repo.path, paths=["foo"])
  165. class LogTests(PorcelainTestCase):
  166. def test_simple(self):
  167. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  168. [3, 1, 2]])
  169. self.repo.refs["HEAD"] = c3.id
  170. outstream = StringIO()
  171. porcelain.log(self.repo.path, outstream=outstream)
  172. self.assertTrue(outstream.getvalue().startswith("-" * 50))
  173. class ShowTests(PorcelainTestCase):
  174. def test_simple(self):
  175. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  176. [3, 1, 2]])
  177. self.repo.refs["HEAD"] = c3.id
  178. outstream = StringIO()
  179. porcelain.show(self.repo.path, committish=c3.id, outstream=outstream)
  180. self.assertTrue(outstream.getvalue().startswith("-" * 50))
  181. class SymbolicRefTests(PorcelainTestCase):
  182. def test_set_wrong_symbolic_ref(self):
  183. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  184. [3, 1, 2]])
  185. self.repo.refs["HEAD"] = c3.id
  186. outstream = StringIO()
  187. self.assertRaises(ValueError, porcelain.symbolic_ref, self.repo.path, 'foobar')
  188. def test_set_force_wrong_symbolic_ref(self):
  189. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  190. [3, 1, 2]])
  191. self.repo.refs["HEAD"] = c3.id
  192. porcelain.symbolic_ref(self.repo.path, 'force_foobar', force=True)
  193. #test if we actually changed the file
  194. new_ref = self.repo.get_named_file('HEAD').read()
  195. self.assertEqual(new_ref, 'ref: refs/heads/force_foobar\n')
  196. def test_set_symbolic_ref(self):
  197. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  198. [3, 1, 2]])
  199. self.repo.refs["HEAD"] = c3.id
  200. porcelain.symbolic_ref(self.repo.path, 'master')
  201. def test_set_symbolic_ref_other_than_master(self):
  202. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  203. [3, 1, 2]], attrs=dict(refs='develop'))
  204. self.repo.refs["HEAD"] = c3.id
  205. self.repo.refs["refs/heads/develop"] = c3.id
  206. porcelain.symbolic_ref(self.repo.path, 'develop')
  207. #test if we actually changed the file
  208. new_ref = self.repo.get_named_file('HEAD').read()
  209. self.assertEqual(new_ref, 'ref: refs/heads/develop\n')
  210. class DiffTreeTests(PorcelainTestCase):
  211. def test_empty(self):
  212. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  213. [3, 1, 2]])
  214. self.repo.refs["HEAD"] = c3.id
  215. outstream = StringIO()
  216. porcelain.diff_tree(self.repo.path, c2.tree, c3.tree, outstream=outstream)
  217. self.assertEquals(outstream.getvalue(), "")
  218. class CommitTreeTests(PorcelainTestCase):
  219. def test_simple(self):
  220. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  221. [3, 1, 2]])
  222. b = Blob()
  223. b.data = "foo the bar"
  224. t = Tree()
  225. t.add("somename", 0100644, b.id)
  226. self.repo.object_store.add_object(t)
  227. self.repo.object_store.add_object(b)
  228. sha = porcelain.commit_tree(
  229. self.repo.path, t.id, message="Withcommit.",
  230. author="Joe <joe@example.com>",
  231. committer="Jane <jane@example.com>")
  232. self.assertTrue(type(sha) is str)
  233. self.assertEquals(len(sha), 40)
  234. class RevListTests(PorcelainTestCase):
  235. def test_simple(self):
  236. c1, c2, c3 = build_commit_graph(self.repo.object_store, [[1], [2, 1],
  237. [3, 1, 2]])
  238. outstream = StringIO()
  239. porcelain.rev_list(
  240. self.repo.path, [c3.id], outstream=outstream)
  241. self.assertEquals(
  242. "%s\n%s\n%s\n" % (c3.id, c2.id, c1.id),
  243. outstream.getvalue())