mirror of
https://github.com/certbot/certbot.git
synced 2026-03-02 05:10:24 -05:00
- Finishing refactor of postconf/postfix command-line utilities - Plugin uses starttls_policy plugin to specify per-domain policies Cleaning up TLS policy code. Print warning when setting configuration parameter that is overridden by master. Update client to use new policy API Cleanup and test fixes Documentation fix smaller fixes Policy is now an enhancement and reverting works Added a README, and small documentation fixes throughout Moving testing infra from starttls repo to certbot-postfix fixing tests and lint Changes against new policy API starttls-everywhere => starttls-policy testing(postfix): Added more varieties of certificates to test against. Moar fixes against policy API. Address comments on README and setup.py Address small comments on postconf and util Address comments in installer Python 3 fixes and Postconf tester extends TempDir test class Mock out postconf calls from tests and test coverage for master overrides More various fixes. Everything minus testing done Remove STARTTLS policy enhancement from this branch. sphinx quickstart 99% test coverage some cleanup and testfixing cleanup leftover files Remove print statement testfix for python 3.4 Revert dockerfile change mypy fix fix(postfix): brad's comments test(postfix): coverage to 100 test(postfix): mypy import mypy types fix(postfix docs): add .rst files and fix build fix(postfix): tls_only and server_only params behave nicely together some cleanup lint fix more comments bump version number
205 lines
8.3 KiB
Python
205 lines
8.3 KiB
Python
"""Tests for certbot_postfix.util."""
|
|
|
|
import subprocess
|
|
import unittest
|
|
|
|
import mock
|
|
|
|
from certbot import errors
|
|
|
|
|
|
class PostfixUtilBaseTest(unittest.TestCase):
|
|
"""Tests for certbot_postfix.util.PostfixUtilBase."""
|
|
|
|
@classmethod
|
|
def _create_object(cls, *args, **kwargs):
|
|
from certbot_postfix.util import PostfixUtilBase
|
|
return PostfixUtilBase(*args, **kwargs)
|
|
|
|
@mock.patch('certbot_postfix.util.verify_exe_exists')
|
|
def test_no_exe(self, mock_verify):
|
|
expected_error = errors.NoInstallationError
|
|
mock_verify.side_effect = expected_error
|
|
self.assertRaises(expected_error, self._create_object, 'nonexistent')
|
|
|
|
def test_object_creation(self):
|
|
with mock.patch('certbot_postfix.util.verify_exe_exists'):
|
|
self._create_object('existent')
|
|
|
|
@mock.patch('certbot_postfix.util.check_all_output')
|
|
def test_call_extends_args(self, mock_output):
|
|
# pylint: disable=protected-access
|
|
with mock.patch('certbot_postfix.util.verify_exe_exists'):
|
|
mock_output.return_value = 'expected'
|
|
postfix = self._create_object('executable')
|
|
postfix._call(['many', 'extra', 'args'])
|
|
mock_output.assert_called_with(['executable', 'many', 'extra', 'args'])
|
|
postfix._call()
|
|
mock_output.assert_called_with(['executable'])
|
|
|
|
def test_create_with_config(self):
|
|
# pylint: disable=protected-access
|
|
with mock.patch('certbot_postfix.util.verify_exe_exists'):
|
|
postfix = self._create_object('exec', 'config_dir')
|
|
self.assertEqual(postfix._base_command, ['exec', '-c', 'config_dir'])
|
|
|
|
class PostfixUtilTest(unittest.TestCase):
|
|
def setUp(self):
|
|
# pylint: disable=protected-access
|
|
from certbot_postfix.util import PostfixUtil
|
|
with mock.patch('certbot_postfix.util.verify_exe_exists'):
|
|
self.postfix = PostfixUtil()
|
|
self.postfix._call = mock.Mock()
|
|
self.mock_call = self.postfix._call
|
|
|
|
def test_test(self):
|
|
self.postfix.test()
|
|
self.mock_call.assert_called_with(['check'])
|
|
|
|
def test_test_raises_error_when_check_fails(self):
|
|
self.mock_call.side_effect = [subprocess.CalledProcessError(1, "")]
|
|
self.assertRaises(errors.MisconfigurationError, self.postfix.test)
|
|
self.mock_call.assert_called_with(['check'])
|
|
|
|
def test_restart_while_running(self):
|
|
self.mock_call.side_effect = [subprocess.CalledProcessError(1, ""), None]
|
|
self.postfix.restart()
|
|
self.mock_call.assert_called_with(['start'])
|
|
|
|
def test_restart_while_not_running(self):
|
|
self.postfix.restart()
|
|
self.mock_call.assert_called_with(['reload'])
|
|
|
|
def test_restart_raises_error_when_reload_fails(self):
|
|
self.mock_call.side_effect = [None, subprocess.CalledProcessError(1, "")]
|
|
self.assertRaises(errors.PluginError, self.postfix.restart)
|
|
self.mock_call.assert_called_with(['reload'])
|
|
|
|
def test_restart_raises_error_when_start_fails(self):
|
|
self.mock_call.side_effect = [
|
|
subprocess.CalledProcessError(1, ""),
|
|
subprocess.CalledProcessError(1, "")]
|
|
self.assertRaises(errors.PluginError, self.postfix.restart)
|
|
self.mock_call.assert_called_with(['start'])
|
|
|
|
class CheckAllOutputTest(unittest.TestCase):
|
|
"""Tests for certbot_postfix.util.check_all_output."""
|
|
|
|
@classmethod
|
|
def _call(cls, *args, **kwargs):
|
|
from certbot_postfix.util import check_all_output
|
|
return check_all_output(*args, **kwargs)
|
|
|
|
@mock.patch('certbot_postfix.util.logger')
|
|
@mock.patch('certbot_postfix.util.subprocess.Popen')
|
|
def test_command_error(self, mock_popen, mock_logger):
|
|
command = 'foo'
|
|
retcode = 42
|
|
output = 'bar'
|
|
err = 'baz'
|
|
|
|
mock_popen().communicate.return_value = (output, err)
|
|
mock_popen().poll.return_value = 42
|
|
|
|
self.assertRaises(subprocess.CalledProcessError, self._call, command)
|
|
log_args = mock_logger.debug.call_args[0]
|
|
for value in (command, retcode, output, err,):
|
|
self.assertTrue(value in log_args)
|
|
|
|
@mock.patch('certbot_postfix.util.subprocess.Popen')
|
|
def test_success(self, mock_popen):
|
|
command = 'foo'
|
|
expected = ('bar', '')
|
|
mock_popen().communicate.return_value = expected
|
|
mock_popen().poll.return_value = 0
|
|
|
|
self.assertEqual(self._call(command), expected)
|
|
|
|
def test_stdout_error(self):
|
|
self.assertRaises(ValueError, self._call, stdout=None)
|
|
|
|
def test_stderr_error(self):
|
|
self.assertRaises(ValueError, self._call, stderr=None)
|
|
|
|
def test_universal_newlines_error(self):
|
|
self.assertRaises(ValueError, self._call, universal_newlines=False)
|
|
|
|
|
|
class VerifyExeExistsTest(unittest.TestCase):
|
|
"""Tests for certbot_postfix.util.verify_exe_exists."""
|
|
|
|
@classmethod
|
|
def _call(cls, *args, **kwargs):
|
|
from certbot_postfix.util import verify_exe_exists
|
|
return verify_exe_exists(*args, **kwargs)
|
|
|
|
@mock.patch('certbot_postfix.util.certbot_util.exe_exists')
|
|
@mock.patch('certbot_postfix.util.plugins_util.path_surgery')
|
|
def test_failure(self, mock_exe_exists, mock_path_surgery):
|
|
mock_exe_exists.return_value = mock_path_surgery.return_value = False
|
|
self.assertRaises(errors.NoInstallationError, self._call, 'foo')
|
|
|
|
@mock.patch('certbot_postfix.util.certbot_util.exe_exists')
|
|
def test_simple_success(self, mock_exe_exists):
|
|
mock_exe_exists.return_value = True
|
|
self._call('foo')
|
|
|
|
@mock.patch('certbot_postfix.util.certbot_util.exe_exists')
|
|
@mock.patch('certbot_postfix.util.plugins_util.path_surgery')
|
|
def test_successful_surgery(self, mock_exe_exists, mock_path_surgery):
|
|
mock_exe_exists.return_value = False
|
|
mock_path_surgery.return_value = True
|
|
self._call('foo')
|
|
|
|
class TestUtils(unittest.TestCase):
|
|
""" Testing random utility functions in util.py
|
|
"""
|
|
def test_report_master_overrides(self):
|
|
from certbot_postfix.util import report_master_overrides
|
|
self.assertRaises(errors.PluginError, report_master_overrides, 'name',
|
|
[('service/type', 'value')])
|
|
# Shouldn't raise error
|
|
report_master_overrides('name', [('service/type', 'value')],
|
|
acceptable_overrides=('value',))
|
|
|
|
def test_no_acceptable_value(self):
|
|
from certbot_postfix.util import is_acceptable_value
|
|
self.assertFalse(is_acceptable_value('name', 'value', None))
|
|
|
|
def test_is_acceptable_value(self):
|
|
from certbot_postfix.util import is_acceptable_value
|
|
self.assertTrue(is_acceptable_value('name', 'value', ('value',)))
|
|
self.assertFalse(is_acceptable_value('name', 'bad', ('value',)))
|
|
|
|
def test_is_acceptable_tuples(self):
|
|
from certbot_postfix.util import is_acceptable_value
|
|
self.assertTrue(is_acceptable_value('name', 'value', ('value', 'value1')))
|
|
self.assertFalse(is_acceptable_value('name', 'bad', ('value', 'value1')))
|
|
|
|
def test_is_acceptable_protocols(self):
|
|
from certbot_postfix.util import is_acceptable_value
|
|
# SSLv2 and SSLv3 are both not supported, unambiguously
|
|
self.assertFalse(is_acceptable_value('tls_mandatory_protocols_lol',
|
|
'SSLv2, SSLv3', None))
|
|
self.assertFalse(is_acceptable_value('tls_protocols_lol',
|
|
'SSLv2, SSLv3', None))
|
|
self.assertFalse(is_acceptable_value('tls_protocols_lol',
|
|
'!SSLv2, !TLSv1', None))
|
|
self.assertFalse(is_acceptable_value('tls_protocols_lol',
|
|
'!SSLv2, SSLv3, !SSLv3, ', None))
|
|
self.assertTrue(is_acceptable_value('tls_protocols_lol',
|
|
'!SSLv2, !SSLv3', None))
|
|
self.assertTrue(is_acceptable_value('tls_protocols_lol',
|
|
'!SSLv3, !TLSv1, !SSLv2', None))
|
|
# TLSv1.2 is supported unambiguously
|
|
self.assertFalse(is_acceptable_value('tls_protocols_lol',
|
|
'TLSv1, TLSv1.1,', None))
|
|
self.assertFalse(is_acceptable_value('tls_protocols_lol',
|
|
'TLSv1.2, !TLSv1.2,', None))
|
|
self.assertTrue(is_acceptable_value('tls_protocols_lol',
|
|
'TLSv1.2, ', None))
|
|
self.assertTrue(is_acceptable_value('tls_protocols_lol',
|
|
'TLSv1, TLSv1.1, TLSv1.2', None))
|
|
|
|
if __name__ == '__main__': # pragma: no cover
|
|
unittest.main()
|