Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 'verify' option #12

Merged
merged 9 commits into from
Nov 9, 2017
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
httsleep Changelog
==================

Version NEXT
-------------
* The kwarg ``verify`` is now supported, allowing users of httsleep to specify
``verify=False`` in the same way as when directly using the ``requests`` library.

Version 0.2.0
-------------
* The shorthand kwargs (``status_code``, ``json``, ``jsonpath``, ``text``, ``callback``)
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Aengus Walton <ventolin@gmail.com>
Patrick Mühlbauer <patrick@opentrash.org>
Oliver Lockwood <oliver.lockwood@cantab.net>
20 changes: 13 additions & 7 deletions httsleep/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class HttSleeper(object):
function that takes the response as an argument returning True.
:param auth: a (username, password) tuple for HTTP authentication.
:param headers: a dict of HTTP headers.
:param verify: Either a boolean, in which case it controls whether we verify the server's
TLS certificate, or a string, in which case it must be a path to a CA
bundle to use. Defaults to ``True``.
:param polling_interval: how many seconds to sleep between requests.
:param max_retries: the maximum number of retries to make, after which
a StopIteration exception is raised.
Expand All @@ -46,7 +49,7 @@ class HttSleeper(object):
"""
def __init__(self, url_or_request, until=None, alarms=None,
status_code=None, json=None, jsonpath=None, text=None, callback=None,
auth=None, headers=None,
auth=None, headers=None, verify=True,
polling_interval=DEFAULT_POLLING_INTERVAL,
max_retries=DEFAULT_MAX_RETRIES,
ignore_exceptions=None,
Expand Down Expand Up @@ -84,6 +87,7 @@ def __init__(self, url_or_request, until=None, alarms=None,
'jsonpath': jsonpath, 'text': text, 'callback': callback}
until.append({k: v for k, v in condition.items() if v})

self.verify = verify
self.until = until
self.alarms = alarms
self.polling_interval = int(polling_interval)
Expand Down Expand Up @@ -145,7 +149,7 @@ def run(self):
"""
while True:
try:
response = self.session.send(self.request.prepare())
response = self.session.send(self.request.prepare(), verify=self.verify)
for condition in self.alarms:
if self.meets_condition(response, condition):
raise Alarm(response, condition)
Expand Down Expand Up @@ -192,9 +196,9 @@ def meets_condition(response, condition):
return True


def httsleep(url_or_request, until=None, alarms=None,
status_code=None, json=None, jsonpath=None, text=None, callback=None,
auth=None, headers=None,
def httsleep(url_or_request, until=None, alarms=None, status_code=None,
json=None, jsonpath=None, text=None, callback=None,
auth=None, headers=None, verify=True,
polling_interval=DEFAULT_POLLING_INTERVAL,
max_retries=DEFAULT_MAX_RETRIES,
ignore_exceptions=None,
Expand All @@ -207,7 +211,9 @@ def httsleep(url_or_request, until=None, alarms=None,
return HttSleeper(
url_or_request, until=until, alarms=alarms, status_code=status_code,
json=json, jsonpath=jsonpath, text=text, callback=callback,
auth=auth, headers=headers, polling_interval=polling_interval,
max_retries=max_retries, ignore_exceptions=ignore_exceptions,
auth=auth, headers=headers, verify=verify,
polling_interval=polling_interval,
max_retries=max_retries,
ignore_exceptions=ignore_exceptions,
loglevel=loglevel
).run()
10 changes: 10 additions & 0 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ def test_headers():
assert obj.request.headers == headers


def test_default_verify():
obj = HttSleeper(URL, CONDITION)
assert obj.verify == True


def test_verify():
obj = HttSleeper(URL, CONDITION, verify=False)
assert obj.verify == False


def test_ignore_exceptions_default_value():
obj = HttSleeper(URL, CONDITION)
assert obj.ignore_exceptions == tuple()
Expand Down
31 changes: 31 additions & 0 deletions tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import mock
import pytest
from requests.exceptions import ConnectionError
from requests import Response

from httsleep.main import HttSleeper, Alarm, DEFAULT_POLLING_INTERVAL

Expand All @@ -22,6 +23,36 @@ def test_run_success():
assert not mock_sleep.called


@httpretty.activate
def test_propagate_verify():
"""Should tell requests to skip SSL verification if verify==False"""
resp = Response()
resp.status_code = 200
httsleep = HttSleeper(URL, {'status_code': 200}, verify=False)
with mock.patch('requests.sessions.Session.send') as mock_session_send:
mock_session_send.return_value = resp
httsleep.run()
assert mock_session_send.called
args, kwargs = mock_session_send.call_args
assert 'verify' in kwargs
assert kwargs['verify'] == False


@httpretty.activate
def test_default_sends_verify_true():
"""Should not send a value for 'verify' to requests by default"""
resp = Response()
resp.status_code = 200
httsleep = HttSleeper(URL, {'status_code': 200})
with mock.patch('requests.sessions.Session.send') as mock_session_send:
mock_session_send.return_value = resp
httsleep.run()
assert mock_session_send.called
args, kwargs = mock_session_send.call_args
assert 'verify' in kwargs
assert kwargs['verify'] == True


@httpretty.activate
def test_run_alarm():
"""Should raise an Alarm when a failure criteria has been reached"""
Expand Down