Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 87af0846528a66d68002fd9718bb38878f113e4e 0 parents
@andymckay authored
5 LICENSE.rst
@@ -0,0 +1,5 @@
+BSD and MPL
+
+Portions of this are from commonware:
+
+https://github.com/jsocol/commonware/blob/master/LICENSE
20 README.rst
@@ -0,0 +1,20 @@
+An experimental nose plugin to block access to external services that you
+really should not be accessing in your unit tests.
+
+To use::
+
+ pip install nose-blockage
+
+Then add the following to your tests::
+
+ --with-blockage
+
+By default it whitelists `localhost` and `127.0.0.1`. To change the whitelist::
+
+ --http-whitelist=some.site,some.other.site
+
+If the code hits a http connection then instead of completing it will raise a
+MockHTTPCall exception. Please go an mock your tests appropriately.
+
+To come, maybe more libs.
+
1  blockage/__init__.py
@@ -0,0 +1 @@
+from blockage.plugins import NoseBlockage
55 blockage/plugin.py
@@ -0,0 +1,55 @@
+import httplib
+import logging
+import os
+import urlparse
+
+NOSE = False
+try:
+ from nose.plugins.base import Plugin
+ NOSE = True
+except ImportError:
+ class Plugin:
+ pass
+
+log = logging.getLogger(__name__)
+
+
+class MockHTTPCall(Exception):
+ # If you don't mock out http calls in your tests, we'll raise an error
+ # for you so you'll remember to do it next time.
+ pass
+
+
+
+class NoseBlockage(Plugin):
+ name = 'blockage'
+
+ def options(self, parse, env=os.environ):
+ import pdb; pdb.set_trace()
+ print parse
+ super(NoseBlockage, self).options(parse, env=env)
+
+ def configure(self, options, conf):
+ import pdb; pdb.set_trace()
+ print options, conf
+ super(NoseBlockage, self).configure(options, conf)
+
+ def begin(self):
+
+ # These are the ES hosts.
+ HTTP_DOMAINS = ['http://127.0.0.1:9200']
+ HTTP_DOMAINS = [urlparse.urlparse(d).netloc for d in HTTP_DOMAINS]
+
+ old = httplib.HTTPConnection
+ def whitelisted(self, host, *args, **kwargs):
+ if host not in HTTP_DOMAINS:
+ print '-', host
+ raise MockHTTPCall(host)
+ print '+', host
+ return old(self, host, *args, **kwargs)
+
+ whitelisted.patched = True
+
+ if not getattr(httplib.HTTPConnection.__init__, 'patched', None):
+ httplib.HTTPConnection.__init__ = whitelisted
+
55 blockage/plugins.py
@@ -0,0 +1,55 @@
+import httplib
+import logging
+import os
+
+NOSE = False
+try:
+ from nose.plugins.base import Plugin
+ NOSE = True
+except ImportError:
+ class Plugin:
+ pass
+
+log = logging.getLogger(__name__)
+
+
+class MockHTTPCall(Exception):
+ # If you don't mock out http calls in your tests, we'll raise an error
+ # for you so you'll remember to do it next time.
+ pass
+
+
+
+class NoseBlockage(Plugin):
+ name = 'blockage'
+ default_http_whitelist = '127.0.0.1,localhost'
+
+ def options(self, parser, env=os.environ):
+ super(NoseBlockage, self).options(parser, env=env)
+ parser.add_option('--http-whitelist', action='store',
+ default=env.get('HTTP_WHITELIST',
+ self.default_http_whitelist),
+ dest='http_whitelist')
+
+ def configure(self, options, conf):
+ self.options = options
+ super(NoseBlockage, self).configure(options, conf)
+ self.http_whitelist = [s.strip() for s in
+ self.options.http_whitelist.split(',')]
+
+ def begin(self):
+ http_whitelist = self.http_whitelist
+
+ def whitelisted(self, host, *args, **kwargs):
+ if isinstance(host, basestring) and host not in http_whitelist:
+ log.warning('Denied HTTP connection to: %s' % host)
+ raise MockHTTPCall(host)
+ log.debug('Allowed HTTP connection to: %s' % host)
+ return self.old(host, *args, **kwargs)
+
+ whitelisted.blockage = True
+
+ if not getattr(httplib.HTTPConnection, 'blockage', False):
+ log.debug('Monkey patching httplib')
+ httplib.HTTPConnection.old = httplib.HTTPConnection.__init__
+ httplib.HTTPConnection.__init__ = whitelisted
28 setup.py
@@ -0,0 +1,28 @@
+from setuptools import setup
+
+
+setup(
+ name='nose-blockage',
+ version='0.1',
+ description='Raise errors when communicating outside of tests',
+ long_description=open('README.rst').read(),
+ author='Andy McKay',
+ author_email='andym@mozilla.com',
+ license='BSD',
+ install_requires=['nose'],
+ packages=['blockage'],
+ url='https://github.com/andymckay/nose-blockage',
+ entry_points={
+ 'nose.plugins.0.10': [
+ 'blockage = blockage:NoseBlockage'
+ ]
+ },
+ include_package_data=True,
+ zip_safe=False,
+ classifiers=[
+ 'Intended Audience :: Developers',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Framework :: Django'
+ ]
+)

0 comments on commit 87af084

Please sign in to comment.
Something went wrong with that request. Please try again.