├── .gitignore ├── CHANGELOG.rst ├── LICENSE ├── MANIFEST.in ├── README.rst ├── pytest_blockage.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | __pycache__ 21 | 22 | # Installer logs 23 | pip-log.txt 24 | 25 | # Unit test / coverage reports 26 | .coverage 27 | .tox 28 | nosetests.xml 29 | 30 | # Translations 31 | *.mo 32 | 33 | # Mr Developer 34 | .mr.developer.cfg 35 | .project 36 | .pydevproject 37 | belt.sqlite 38 | test.sqlite 39 | htmlcov 40 | production.ini 41 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.2.3 (2021-12-21) 5 | ------------------ 6 | 7 | - FIX: sdist package was broken 8 | 9 | 0.2.2 (2019-02-13) 10 | ------------------ 11 | 12 | - FIX: SMTP whitelisting works with python3 as well 13 | 14 | 0.2.1 (2018-12-01) 15 | ------------------ 16 | 17 | - HTTP whitelisting 18 | - SMTP whitelisting 19 | 20 | 0.2.0 (2015-06-22) 21 | ------------------ 22 | 23 | - Added python 3 support 24 | 25 | 0.1 (2013-05-11) 26 | ---------------- 27 | 28 | - Initial Release 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all 9 | copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | SOFTWARE. 18 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include CHANGELOG.rst 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pytest-blockage 2 | =============== 3 | 4 | Disable SMTP and HTTP requests during a test run. 5 | 6 | Based mainly on https://github.com/andymckay/nose-blockage; source is 7 | available at https://github.com/rob-b/pytest-blockage 8 | 9 | Installation 10 | ------------ 11 | 12 | The plugin can be installed via `pypi `_:: 13 | 14 | $ pip install pytest-blockage 15 | 16 | 17 | Usage 18 | ----- 19 | 20 | To activate the plugin the ``--blockage`` parameter should be passed. e.g.:: 21 | 22 | $ py.test package --blockage 23 | 24 | You can whitelist specific hosts:: 25 | 26 | $ py.test package --blockage --blockage-http-whitelist=some_site --blockage-smtp-whitelist=fake_smtp 27 | 28 | Configuration 29 | ------------- 30 | 31 | All settings can be stored in your pytest file, with the same variable names as 32 | the argument names mentioned under usage:: 33 | 34 | blockage=true 35 | blockage-http-whitelist=some_site 36 | blockage-smtp-whitelist=fake_smtp 37 | 38 | 39 | -------------------------------------------------------------------------------- /pytest_blockage.py: -------------------------------------------------------------------------------- 1 | import sys 2 | if sys.version_info[0] < 3: 3 | import httplib 4 | else: 5 | import http.client as httplib 6 | import logging 7 | import smtplib 8 | 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | 13 | class MockHttpCall(Exception): 14 | pass 15 | 16 | 17 | class MockSmtpCall(Exception): 18 | pass 19 | 20 | 21 | def get_string_type(): 22 | try: 23 | return basestring 24 | except NameError: # python3 25 | return str 26 | 27 | 28 | def block_http(whitelist): 29 | def whitelisted(self, host, *args, **kwargs): 30 | if isinstance(host, get_string_type()) and host not in whitelist: 31 | logger.warning('Denied HTTP connection to: %s' % host) 32 | raise MockHttpCall(host) 33 | logger.debug('Allowed HTTP connection to: %s' % host) 34 | return self.old(host, *args, **kwargs) 35 | 36 | whitelisted.blockage = True 37 | 38 | if not getattr(httplib.HTTPConnection, 'blockage', False): 39 | logger.debug('Monkey patching httplib') 40 | httplib.HTTPConnection.old = httplib.HTTPConnection.__init__ 41 | httplib.HTTPConnection.__init__ = whitelisted 42 | 43 | 44 | def block_smtp(whitelist): 45 | def whitelisted(self, host, *args, **kwargs): 46 | if isinstance(host, get_string_type()) and host not in whitelist: 47 | logger.warning('Denied SMTP connection to: %s' % host) 48 | raise MockSmtpCall(host) 49 | logger.debug('Allowed SMTP connection to: %s' % host) 50 | return self.old(host, *args, **kwargs) 51 | 52 | whitelisted.blockage = True 53 | 54 | if not getattr(smtplib.SMTP, 'blockage', False): 55 | logger.debug('Monkey patching smtplib') 56 | smtplib.SMTP.old = smtplib.SMTP.__init__ 57 | smtplib.SMTP.__init__ = whitelisted 58 | 59 | 60 | def pytest_addoption(parser): 61 | group = parser.getgroup('blockage') 62 | group.addoption('--blockage', action='store_true', 63 | help='Block network requests during test run') 64 | parser.addini( 65 | 'blockage', 'Block network requests during test run', default=False) 66 | 67 | group.addoption( 68 | '--blockage-http-whitelist', 69 | action='store', 70 | help='Do not block HTTP requests to this comma separated list of ' 71 | 'hostnames', 72 | default='' 73 | ) 74 | parser.addini( 75 | 'blockage-http-whitelist', 76 | 'Do not block HTTP requests to this comma separated list of hostnames', 77 | default='' 78 | ) 79 | 80 | group.addoption( 81 | '--blockage-smtp-whitelist', 82 | action='store', 83 | help='Do not block SMTP requests to this comma separated list of ' 84 | 'hostnames', 85 | default='' 86 | ) 87 | parser.addini( 88 | 'blockage-smtp-whitelist', 89 | 'Do not block SMTP requests to this comma separated list of hostnames', 90 | default='' 91 | ) 92 | 93 | 94 | def pytest_sessionstart(session): 95 | config = session.config 96 | 97 | if config.option.blockage or config.getini('blockage'): 98 | http_whitelist_str = config.option.blockage_http_whitelist or config.getini('blockage-http-whitelist') 99 | http_whitelist = http_whitelist_str.split(',') 100 | 101 | smtp_whitelist_str = config.option.blockage_smtp_whitelist or config.getini('blockage-smtp-whitelist') 102 | smtp_whitelist = smtp_whitelist_str.split(',') 103 | 104 | block_http(http_whitelist) 105 | block_smtp(smtp_whitelist) 106 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | 4 | setup( 5 | name='pytest-blockage', 6 | version='0.2.4', 7 | description='Disable network requests during a test run.', 8 | long_description=(open('README.rst').read() + 9 | open('CHANGELOG.rst').read()), 10 | long_description_content_type='text/x-rst', 11 | url="https://github.com/rob-b/pytest-blockage", 12 | license='BSD', 13 | install_requires=['pytest'], 14 | py_modules=['pytest_blockage'], 15 | entry_points={'pytest11': ['blockage = pytest_blockage']}, 16 | include_package_data=True, 17 | zip_safe=False, 18 | classifiers=[ 19 | 'Intended Audience :: Developers', 20 | 'Natural Language :: English', 21 | 'Operating System :: OS Independent', 22 | ] 23 | ) 24 | --------------------------------------------------------------------------------