Skip to content

Commit

Permalink
Add exception support.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein committed Dec 9, 2020
1 parent 1419afe commit 50985a5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
9 changes: 8 additions & 1 deletion plugins/lookup/open_url_test_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
from ansible.errors import AnsibleLookupError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.urls import open_url
from ansible.module_utils.six.moves.urllib.error import HTTPError

from ansible.utils.display import Display

Expand All @@ -80,6 +81,8 @@ def run(self, terms, variables=None, **kwargs):
method = self.get_option('method')
headers = self.get_option('headers')
data = self.get_option('data')
if data is not None:
data = base64.b64decode(data)

result = []

Expand All @@ -89,11 +92,15 @@ def run(self, terms, variables=None, **kwargs):
content = response.read()
headers = dict([(k, v) for k, v in response.headers.items()])
code = response.code
except HTTPError as exc:
content = exc.read()
headers = dict(exc.info())
code = exc.code
except Exception as exc:
raise AnsibleLookupError('Error while {method}ing {url}: {error}'.format(
method=method,
url=url,
error=exc,
error=str(exc),
))

result.append(dict(
Expand Down
25 changes: 23 additions & 2 deletions tests/unit/plugins/lookup/test_open_url_test_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

import pytest

from ansible.errors import AnsibleLookupError
from ansible.plugins.loader import lookup_loader

from ansible_collections.community.internal_test_tools.tests.unit.utils.open_url_framework import (
OpenUrlCall,
OpenUrlProxy,
)

from ansible_collections.community.internal_test_tools.plugins.lookup import open_url_test_lookup

from ansible.plugins.loader import lookup_loader

from ansible_collections.community.internal_test_tools.tests.unit.compat.unittest import TestCase
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import (
patch,
Expand Down Expand Up @@ -44,3 +45,23 @@ def test_basic(self):
assert len(result) == 1
assert result[0]['status'] == 200
assert result[0]['content'] == base64.b64encode('hello'.encode('utf-8')).decode('utf-8')

def test_error(self):
open_url = OpenUrlProxy([
OpenUrlCall('PUT', 404)
.exception(lambda: Exception('foo bar!'))
.expect_header('foo', 'bar')
.expect_header_unset('baz')
.expect_url('http://example.com'),
])
with patch('ansible_collections.community.internal_test_tools.plugins.lookup.open_url_test_lookup.open_url', open_url):
with pytest.raises(AnsibleLookupError) as e:
self.lookup.run(
['http://example.com', 'http://example.org'],
[],
method='PUT',
headers=dict(foo='bar'),
)
open_url.assert_is_done()

assert e.value.message == 'Error while PUTing http://example.com: foo bar!'
17 changes: 16 additions & 1 deletion tests/unit/utils/open_url_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def __init__(self, method, status):
'HTTP method names are case-sensitive and should be upper-case (RFCs 7230 and 7231)'
self.method = method
self.status = status
self.exception_generator = None
self.body = None
self.headers = {}
self.error_data = {}
Expand All @@ -116,12 +117,23 @@ def __init__(self, method, status):
self.form_values = {}
self.form_values_one = {}

def exception(self, exception_generator):
'''
Builder method to raise an exception in the ``open_url()`` call.
Must be a function that returns an exception.
'''
self.exception_generator = exception_generator
assert self.error_data.get('body') is None, 'Error body must not be given'
assert self.body is None, 'Result must not be given if exception generator is provided'
return self

def result(self, body):
'''
Builder method to set return body of the ``open_url()`` call. Must be a bytes string.
'''
self.body = body
assert self.error_data.get('body') is None, 'Error body must not be given'
assert self.error_data.get('body') is None, 'Error body must not be given if body is provided'
assert self.exception_generator is None, 'Exception generator must not be given if body is provided'
return self

def result_str(self, str_body):
Expand All @@ -144,6 +156,7 @@ def result_error(self, msg, body=None):
if body is not None:
self.error_data['body'] = body
assert self.body is None, 'Result must not be given if error body is provided'
assert self.exception_generator is None, 'Exception generator must not be given if error is provided'
return self

def expect_url(self, url):
Expand Down Expand Up @@ -274,6 +287,8 @@ def __call__(self, url, data=None, headers=None, method=None, use_proxy=True,
self._validate_form(call, data)

# Compose result
if call.exception_generator:
raise call.exception_generator()
info = dict()
for k, v in call.headers.items():
info[k.lower()] = v
Expand Down

0 comments on commit 50985a5

Please sign in to comment.