Patch out urllib monkeypatching when installed, adds tests for behavior

This commit is contained in:
Andrew Gross
2016-10-11 18:54:20 -04:00
parent 7c58a3ceff
commit 226d294d9b
5 changed files with 123 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ matrix:
env:
- TEST_TYPE=unit
- TEST_TYPE=functional
- TEST_TYPE=pyopenssl
install:
- pip install -r development.txt

View File

@@ -35,6 +35,12 @@ functional: prepare
@echo "Running functional tests ..."
@nosetests --rednose -x --with-coverage --cover-package=httpretty -s tests/functional
pyopenssl: prepare
@echo "Running PyOpenSSL mocking tests ..."
@pip install --quiet pyOpenSSL==16.1.0
@pip install --quiet ndg-httpsclient==0.4.2
@nosetests --rednose -x --with-coverage --cover-package=httpretty -s tests/pyopenssl
clean:
@printf "Cleaning up files that are already in .gitignore... "
@for pattern in `cat .gitignore`; do rm -rf $$pattern; done

View File

@@ -103,6 +103,14 @@ except ImportError: # pragma: no cover
ssl = None
# used to handle error caused by ndg-httpsclient
try: # pragma: no cover
from requests.packages.urllib3.contrib.pyopenssl import inject_into_urllib3, extract_from_urllib3
pyopenssl_override = True
except ImportError: # pragma: no cover
pyopenssl_override = False
DEFAULT_HTTP_PORTS = frozenset([80])
POTENTIAL_HTTP_PORTS = set(DEFAULT_HTTP_PORTS)
DEFAULT_HTTPS_PORTS = frozenset([443])
@@ -1104,6 +1112,10 @@ class httpretty(HttpBaseClass):
ssl.sslwrap_simple = old_sslwrap_simple
ssl.__dict__['sslwrap_simple'] = old_sslwrap_simple
if pyopenssl_override:
# Replace PyOpenSSL Monkeypatching
inject_into_urllib3()
@classmethod
def is_enabled(cls):
return cls._is_enabled
@@ -1150,6 +1162,9 @@ class httpretty(HttpBaseClass):
ssl.sslwrap_simple = fake_wrap_socket
ssl.__dict__['sslwrap_simple'] = fake_wrap_socket
if pyopenssl_override:
# Remove PyOpenSSL monkeypatch - use the default implementation
extract_from_urllib3()
class httprettized(object):

View File

@@ -0,0 +1,28 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2015> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
import warnings
warnings.simplefilter('ignore')

View File

@@ -0,0 +1,73 @@
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
# <HTTPretty - HTTP client mock for Python>
# Copyright (C) <2011-2015> Gabriel Falcão <gabriel@nacaolivre.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import requests
from mock import patch, Mock
from httpretty import HTTPretty, httprettified
from sure import expect
from requests.packages.urllib3.contrib.pyopenssl import inject_into_urllib3, extract_from_urllib3
@httprettified
def test_httpretty_overrides_when_pyopenssl_installed():
('HTTPretty should remove PyOpenSSLs urllib3 mock if it is installed')
# When we run Httpretty with PyOpenSSL and ndg-httpsclient installed
from httpretty.core import pyopenssl_override
# Then we override pyopenssl
pyopenssl_override.should.be.true
# And HTTPretty works successfully
HTTPretty.register_uri(HTTPretty.GET, "https://yipit.com/",
body="Find the best daily deals")
response = requests.get('https://yipit.com')
expect(response.text).to.equal('Find the best daily deals')
expect(HTTPretty.last_request.method).to.equal('GET')
expect(HTTPretty.last_request.path).to.equal('/')
@httprettified
def test_httpretty_fails_when_pyopenssl_is_not_replaced():
('HTTPretty should fail if PyOpenSSL is installed and we do not remove the monkey patch')
# When we don't replace the PyOpenSSL monkeypatch
inject_into_urllib3()
# And we use HTTPretty on as ssl site
HTTPretty.register_uri(HTTPretty.GET, "https://yipit.com/",
body="Find the best daily deals")
# Then we get an SSL error
requests.get.when.called_with('https://yipit.com').should.throw(requests.exceptions.SSLError)
# Undo injection after test
extract_from_urllib3()