13_test_gbp_pq.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # vim: set fileencoding=utf-8 :
  2. # (C) 2012,2015 Guido Günther <agx@sigxcpu.org>
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, please see
  15. # <http://www.gnu.org/licenses/>
  16. """Test L{gbp.pq}"""
  17. from . import context
  18. from . import testutils
  19. import os
  20. import unittest
  21. from gbp.scripts.pq import generate_patches, export_patches
  22. import gbp.scripts.common.pq as pq
  23. import gbp.patch_series
  24. class TestApplyAndCommit(testutils.DebianGitTestRepo):
  25. """Test L{gbp.pq}'s apply_and_commit"""
  26. def setUp(self):
  27. testutils.DebianGitTestRepo.setUp(self)
  28. self.add_file('bar')
  29. def test_apply_and_commit_patch(self):
  30. """Test applying a single patch"""
  31. patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
  32. pq.apply_and_commit_patch(self.repo, patch, None)
  33. self.assertIn('foo', self.repo.list_files())
  34. def test_topic(self):
  35. """Test if setting a topic works"""
  36. patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
  37. pq.apply_and_commit_patch(self.repo, patch, None, topic='foobar')
  38. info = self.repo.get_commit_info('HEAD')
  39. self.assertIn('Gbp-Pq: Topic foobar', info['body'])
  40. def test_name(self):
  41. """Test if setting a name works"""
  42. patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
  43. pq.apply_and_commit_patch(self.repo, patch, None, name='foobar')
  44. info = self.repo.get_commit_info('HEAD')
  45. self.assertIn('Gbp-Pq: Name foobar', info['body'])
  46. @unittest.skipIf(not os.path.exists('/usr/bin/dpkg'), 'Dpkg not found')
  47. def test_debian_missing_author(self):
  48. """
  49. Check if we parse the author from debian control
  50. if it's missing in the patch.
  51. """
  52. def _check_log(msg):
  53. self.assertEqual(msg, "Patch 'foo.patch' has no authorship "
  54. "information, using 'Guido Günther <gg@godiug.net>'")
  55. patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
  56. # Overwrite data parsed from patch:
  57. patch.author
  58. patch.info['author'] = None
  59. patch.info['email'] = None
  60. # Fake a control file
  61. self.add_file("debian/control",
  62. "Maintainer: Guido Günther <gg@godiug.net>")
  63. maintainer = pq.get_maintainer_from_control(self.repo)
  64. orig_warn = gbp.log.warn
  65. gbp.log.warn = _check_log
  66. pq.apply_and_commit_patch(self.repo, patch, maintainer)
  67. gbp.log.warn = orig_warn
  68. info = self.repo.get_commit_info('HEAD')
  69. self.assertEqual(info['author'].email, 'gg@godiug.net')
  70. self.assertIn('foo', self.repo.list_files())
  71. class TestApplySinglePatch(testutils.DebianGitTestRepo):
  72. """Test L{gbp.pq}'s apply_single_patch"""
  73. def setUp(self):
  74. testutils.DebianGitTestRepo.setUp(self)
  75. self.add_file('bar')
  76. def test_apply_single_patch(self):
  77. """Test applying a single patch"""
  78. patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
  79. pq.apply_single_patch(self.repo, 'master', patch, None)
  80. self.assertIn('foo', self.repo.list_files())
  81. class TestWritePatch(testutils.DebianGitTestRepo):
  82. """Test L{gbp.pq}'s write_patch """
  83. def setUp(self):
  84. testutils.DebianGitTestRepo.setUp(self)
  85. self.add_file('bar', 'bar')
  86. def tearDown(self):
  87. context.teardown()
  88. def _test_generate_patches(self, changes, expected_patches, opts):
  89. self.assertEqual(len(changes), len(expected_patches))
  90. d = context.new_tmpdir(__name__)
  91. expected_paths = [os.path.join(str(d), n) for n in expected_patches ]
  92. # Commit changes
  93. for c in changes:
  94. self.add_file(c[0], c[1], c[2])
  95. # Write it out as patch and check its existence
  96. origin = 'HEAD~%d' % len(changes)
  97. patchfiles = generate_patches(self.repo, origin, 'HEAD', str(d), opts)
  98. for expected in expected_paths:
  99. self.assertIn(expected, patchfiles)
  100. self.assertTrue(os.path.exists(expected))
  101. # Reapply the patch to a new branch
  102. self.repo.create_branch('testapply', origin)
  103. self.repo.set_branch('testapply')
  104. for expected in expected_paths:
  105. self.repo.apply_patch(expected)
  106. self.repo.commit_all("foo")
  107. diff = self.repo.diff('master', 'testapply')
  108. # Branches must be identical afterwards
  109. self.assertEqual('', diff)
  110. def test_generate_patches(self):
  111. """Test generation of patches"""
  112. class opts:
  113. patch_numbers = False
  114. renumber = False
  115. patch_num_format = '%04d-'
  116. expected_patches = [ 'gbptest/added-foo.patch',
  117. 'gbptest/patchname.diff' ]
  118. changes = [ ('foo', 'foo', ("added foo\n\n"
  119. "Gbp-Pq: Topic gbptest")),
  120. ('baz', 'baz', ("added bar\n\n"
  121. "Gbp-Pq: Topic gbptest\n"
  122. "Gbp-Pq: Name patchname.diff")) ]
  123. self._test_generate_patches(changes, expected_patches, opts)
  124. def test_generate_renumbered_patches(self):
  125. """Test generation of renumbered patches"""
  126. class opts:
  127. patch_numbers = True
  128. renumber = True
  129. patch_num_format = '%02d_'
  130. expected_patches = [ 'gbptest/01_added-foo.patch',
  131. 'gbptest/02_patchname.diff' ]
  132. changes = [ ('foo', 'foo', ("added foo\n\n"
  133. "Gbp-Pq: Topic gbptest")),
  134. ('baz', 'baz', ("added bar\n\n"
  135. "Gbp-Pq: Topic gbptest\n"
  136. "Gbp-Pq: Name 099-patchname.diff")) ]
  137. self._test_generate_patches(changes, expected_patches, opts)
  138. def test_generate_patches_with_name_clashes(self):
  139. """Test generation of patches which have name clashes"""
  140. class opts:
  141. patch_numbers = False
  142. renumber = True
  143. patch_num_format = '%02d_'
  144. expected_patches = [ 'gbptest/added-foo.patch',
  145. 'gbptest/patchname.diff',
  146. 'gbptest/patchname-1.diff',
  147. 'gbptest/patchname-2.diff' ]
  148. changes = [ ('foo', 'foo', ("added foo\n\n"
  149. "Gbp-Pq: Topic gbptest")),
  150. ('baz', 'baz', ("added bar\n\n"
  151. "Gbp-Pq: Topic gbptest\n"
  152. "Gbp-Pq: Name 099-patchname.diff")),
  153. ('qux', 'qux', ("added qux\n\n"
  154. "Gbp-Pq: Topic gbptest\n"
  155. "Gbp-Pq: Name 100-patchname.diff")),
  156. ('norf', 'norf', ("added norf\n\n"
  157. "Gbp-Pq: Topic gbptest\n"
  158. "Gbp-Pq: Name 101-patchname.diff")) ]
  159. self._test_generate_patches(changes, expected_patches, opts)
  160. class TestExport(testutils.DebianGitTestRepo):
  161. class Options(object):
  162. drop = True
  163. patch_numbers = False
  164. def setUp(self):
  165. testutils.DebianGitTestRepo.setUp(self)
  166. self.add_file('bar', 'bar')
  167. def test_drop(self):
  168. """Test if we drop the patch-queue branch with --drop"""
  169. repo = self.repo
  170. start = repo.get_branch()
  171. pq_branch = os.path.join('patch-queue', start)
  172. pq.switch_pq(repo, start)
  173. self.assertEqual(repo.get_branch(), pq_branch)
  174. export_patches(repo, pq_branch, TestExport.Options)
  175. self.assertEqual(repo.get_branch(), start)
  176. self.assertFalse(repo.has_branch(pq_branch))
  177. class TestParseGbpCommand(unittest.TestCase):
  178. def test_empty_body(self):
  179. """Test command filtering with an empty body"""
  180. info = {'body': ''}
  181. (cmds, body) = pq.parse_gbp_commands(info, ['tag'], ['cmd1'], ['cmd2'])
  182. self.assertEquals(cmds, {})
  183. self.assertEquals(body, '')
  184. def test_noarg_cmd(self):
  185. orig_body = '\n'.join(["Foo",
  186. "tag: cmd1"])
  187. info = {'body': orig_body}
  188. (cmds, body) = pq.parse_gbp_commands(info, 'tag', ['cmd'], ['argcmd'])
  189. self.assertEquals(cmds, {'cmd': None})
  190. self.assertEquals(body, orig_body)
  191. def test_filter_cmd(self):
  192. orig_body = '\n'.join(["Foo",
  193. "tag: cmd1"])
  194. info = {'body': orig_body}
  195. (cmds, body) = pq.parse_gbp_commands(info, 'tag', ['cmd'], ['argcmd'], ['cmd'])
  196. self.assertEquals(cmds, {'cmd': None})
  197. self.assertEquals(body, 'Foo')
  198. def _patch_path(name):
  199. return os.path.join(context.projectdir, 'tests/data', name)