mirror of
https://github.com/AdaCore/git-hooks.git
synced 2026-02-12 12:43:11 -08:00
The goal of this commit is to include the updates.sendmail module in our testing strategy, in order to make sure that the hooks are passing email data down to the sendmail program without issues. This will become particularly important when we switch over to using Python 3.x, because of the strong distinction between bytes and strings with newer versions of Python which can cause a lot problems. Hence the need to use this code during our testing. The main strategy introduced by this commit to achieve this is fairly simple: The testsuite framework introduces a new minimal script to be called in place of the standard sendmail. A new environment variable called GIT_HOOKS_SENDMAIL is introduced allowing the testsuite to tell the hooks to use its own (fake) sendmail instead of the system one. With that in place, the old code bypassing the use of updates.sendmail can be removed, thus allowing the testsuite to include it as part of the testing. The testsuite's (fake) sendmail script was written in a way to mimick the old bypassing code, so there is no change in output. Parallel to that, the hooks are enhanced to check that we can indeed find sendmail, and otherwise return immediately with an error if not. This way, we avoid emails silently being dropped due to the missing sendmail. A couple of testcases are also added to double-check some specific error situations. Note that I tried to think of ways to split this patch into smaller individual parts, but couldn't really find a way to do so in a meaningful way, while at the same time producing a commit where the coverage report stays clean (0 lines missed). TN: U530-006 (transition to Python 3.x) TN: U924-032 (test for sendmail not found) TN: U924-034 (test for sendmail override when in testsuite mode) Change-Id: I74b993592ec6d701347bbca5283a42e037411f1c
120 lines
4.4 KiB
Python
120 lines
4.4 KiB
Python
#!/usr/bin/env python
|
|
"""Usage: run-test [options] test_dir
|
|
|
|
Run a git-hooks test located in test_dir.
|
|
"""
|
|
from __future__ import print_function
|
|
|
|
from gnatpython.ex import Run
|
|
from gnatpython.fileutils import find, cd, mv
|
|
from gnatpython.main import Main
|
|
from gnatpython.testdriver import TestRunner, add_run_test_options
|
|
|
|
import os
|
|
from os.path import abspath, dirname, isdir
|
|
import sys
|
|
|
|
|
|
class TestGitHooks(TestRunner):
|
|
|
|
def prepare_working_space(self):
|
|
"""Prepare the working space.
|
|
"""
|
|
root_dir = dirname(dirname(dirname(abspath(sys.argv[0]))))
|
|
# First, perform the normal preparations (create the working
|
|
# space, copy the testcase, etc).
|
|
TestRunner.prepare_working_space(self)
|
|
src_dir = '%s/src' % self.work_dir
|
|
|
|
# Next, unpack the git repositories used by this testcase.
|
|
current_dir = os.getcwd()
|
|
cd(src_dir)
|
|
p = Run(['%s/testsuite/bin/unpack-test-repos' % root_dir],
|
|
parse_shebang=True)
|
|
if p.status != 0:
|
|
print(p.out, file=sys.stderr)
|
|
sys.exit(p.status)
|
|
cd(current_dir)
|
|
|
|
# And finally, "install" a copy of the git hooks in the bare
|
|
# repository. Avoid a copy, and simply create a link, which
|
|
# is actually what we do in practice for our real repositories.
|
|
# We have to do this here, because we need to know what the
|
|
# source directory is (the test script gets run in a temporary
|
|
# directory, without any information where the sources are).
|
|
git_dir = '%s/bare/repo.git' % src_dir
|
|
if isdir('%s/.git' % git_dir):
|
|
# This is a non-bare repository (a bit unusual, but
|
|
# supported as well). In that case, the git dir is
|
|
# that .git/ subdirectory.
|
|
git_dir = '%s/.git' % git_dir
|
|
os.symlink('%s/hooks' % root_dir, '%s/hooks' % git_dir)
|
|
|
|
# Also, tell the hooks to use our fake (syslog) logger,
|
|
# rather than the real logger. Usually, we do this sort
|
|
# of thing in the testcase.Setup method, but we need
|
|
# to know the testsuite root dir, which is no longer
|
|
# accessible once we reach that point.
|
|
os.environ['GIT_HOOKS_LOGGER'] = \
|
|
'%s/testsuite/bin/stdout-logger' % root_dir
|
|
|
|
# Similarly, tell the hooks to use our fake sendmail script,
|
|
# rather than the real one (we want those emails to be dumped
|
|
# on stdout, rather than actually sent out).
|
|
os.environ["GIT_HOOKS_SENDMAIL"] = os.path.join(
|
|
root_dir, "testsuite", "bin", "stdout-sendmail-wrapper")
|
|
|
|
def apply_output_filter(self, str_list):
|
|
"""The test is succesful iff the output ends with `OK'.
|
|
"""
|
|
if str_list and str_list[-1] == 'OK':
|
|
return []
|
|
return str_list
|
|
|
|
def write_results(self):
|
|
"""Keep coverage data if needed.
|
|
"""
|
|
TestRunner.write_results(self)
|
|
if 'COVERAGE_DIR' in os.environ:
|
|
for covf in find(self.work_dir, '.coverage*'):
|
|
mv(covf, os.environ['COVERAGE_DIR'])
|
|
|
|
|
|
def main():
|
|
"""Run a git-hooks test.
|
|
"""
|
|
m = Main()
|
|
add_run_test_options(m)
|
|
m.parse_args()
|
|
if not m.args:
|
|
sys.exit("Error: 1 argument expected. See -h")
|
|
|
|
if m.options.restricted_discs is not None:
|
|
m.options.restricted_discs = m.options.restricted_discs.split(',')
|
|
|
|
# Before running the testcase, unset various environment variables
|
|
# that the hooks respond to. We do not want the user environment
|
|
# to influence the hooks' behavior during testing.
|
|
for var_name in ('GIT_HOOKS_CVS_CHECK', 'GIT_HOOKS_DEBUG_LEVEL'):
|
|
if var_name in os.environ:
|
|
del os.environ[var_name]
|
|
|
|
t = TestGitHooks(m.args[0],
|
|
m.options.discs,
|
|
m.options.output_dir,
|
|
m.options.tmp,
|
|
m.options.enable_cleanup,
|
|
m.options.restricted_discs,
|
|
len(m.args) > 1 and m.args[1:] or None,
|
|
m.options.failed_only)
|
|
# Change the name of the testcase script ("test.cmd" or "test.py").
|
|
# This is to allow us to implement a step towards moving this testsuite
|
|
# to a pytest-based testsuite, where "test.py" isn't a name that pytest
|
|
# will consider when looking for testcases.
|
|
t.opt_results["CMD"] = "run_test.py"
|
|
t.execute()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|