test_hooks.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. # test_hooks.py -- Tests for executing hooks
  2. #
  3. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  4. # General Public License as public by the Free Software Foundation; version 2.0
  5. # or (at your option) any later version. You can redistribute it and/or
  6. # modify it under the terms of either of these two licenses.
  7. #
  8. # Unless required by applicable law or agreed to in writing, software
  9. # distributed under the License is distributed on an "AS IS" BASIS,
  10. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. # See the License for the specific language governing permissions and
  12. # limitations under the License.
  13. #
  14. # You should have received a copy of the licenses; if not, see
  15. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  16. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  17. # License, Version 2.0.
  18. #
  19. """Tests for executing hooks."""
  20. import os
  21. import stat
  22. import shutil
  23. import tempfile
  24. from dulwich import errors
  25. from dulwich.hooks import (
  26. PreCommitShellHook,
  27. PostCommitShellHook,
  28. CommitMsgShellHook,
  29. )
  30. from dulwich.tests import TestCase
  31. class ShellHookTests(TestCase):
  32. def setUp(self):
  33. super(ShellHookTests, self).setUp()
  34. if os.name != 'posix':
  35. self.skipTest('shell hook tests requires POSIX shell')
  36. def test_hook_pre_commit(self):
  37. pre_commit_fail = """#!/bin/sh
  38. exit 1
  39. """
  40. pre_commit_success = """#!/bin/sh
  41. exit 0
  42. """
  43. repo_dir = os.path.join(tempfile.mkdtemp())
  44. os.mkdir(os.path.join(repo_dir, 'hooks'))
  45. self.addCleanup(shutil.rmtree, repo_dir)
  46. pre_commit = os.path.join(repo_dir, 'hooks', 'pre-commit')
  47. hook = PreCommitShellHook(repo_dir)
  48. with open(pre_commit, 'w') as f:
  49. f.write(pre_commit_fail)
  50. os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  51. self.assertRaises(errors.HookError, hook.execute)
  52. with open(pre_commit, 'w') as f:
  53. f.write(pre_commit_success)
  54. os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  55. hook.execute()
  56. def test_hook_commit_msg(self):
  57. commit_msg_fail = """#!/bin/sh
  58. exit 1
  59. """
  60. commit_msg_success = """#!/bin/sh
  61. exit 0
  62. """
  63. repo_dir = os.path.join(tempfile.mkdtemp())
  64. os.mkdir(os.path.join(repo_dir, 'hooks'))
  65. self.addCleanup(shutil.rmtree, repo_dir)
  66. commit_msg = os.path.join(repo_dir, 'hooks', 'commit-msg')
  67. hook = CommitMsgShellHook(repo_dir)
  68. with open(commit_msg, 'w') as f:
  69. f.write(commit_msg_fail)
  70. os.chmod(commit_msg, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  71. self.assertRaises(errors.HookError, hook.execute, b'failed commit')
  72. with open(commit_msg, 'w') as f:
  73. f.write(commit_msg_success)
  74. os.chmod(commit_msg, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  75. hook.execute(b'empty commit')
  76. def test_hook_post_commit(self):
  77. (fd, path) = tempfile.mkstemp()
  78. os.close(fd)
  79. post_commit_msg = """#!/bin/sh
  80. rm """ + path + "\n"
  81. post_commit_msg_fail = """#!/bin/sh
  82. exit 1
  83. """
  84. repo_dir = os.path.join(tempfile.mkdtemp())
  85. os.mkdir(os.path.join(repo_dir, 'hooks'))
  86. self.addCleanup(shutil.rmtree, repo_dir)
  87. post_commit = os.path.join(repo_dir, 'hooks', 'post-commit')
  88. hook = PostCommitShellHook(repo_dir)
  89. with open(post_commit, 'w') as f:
  90. f.write(post_commit_msg_fail)
  91. os.chmod(post_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  92. self.assertRaises(errors.HookError, hook.execute)
  93. with open(post_commit, 'w') as f:
  94. f.write(post_commit_msg)
  95. os.chmod(post_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
  96. hook.execute()
  97. self.assertFalse(os.path.exists(path))