Skip to content

Commit d5cb437

Browse files
committed
Increase coverage, better test iterator for stream
1 parent 7be8ede commit d5cb437

File tree

6 files changed

+60
-43
lines changed

6 files changed

+60
-43
lines changed

consulate/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
from consulate.client import Consul
66

77
from consulate.exceptions import (ConsulateException,
8+
ClientError,
89
ServerError,
910
ACLDisabled,
1011
Forbidden,
1112
NotFound,
12-
LockFailure)
13+
LockFailure,
14+
RequestError)
1315

1416
import logging
1517
from logging import NullHandler
@@ -24,9 +26,11 @@
2426
__version__,
2527
Consul,
2628
ConsulateException,
29+
ClientError,
2730
ServerError,
2831
ACLDisabled,
2932
Forbidden,
3033
NotFound,
31-
LockFailure
34+
LockFailure,
35+
RequestError
3236
]

consulate/adapters.py

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ def delete(self, uri):
7070
7171
"""
7272
LOGGER.debug("DELETE %s", uri)
73-
return self._process_response(
74-
self.session.delete(uri, timeout=self.timeout))
73+
return api.Response(self.session.delete(uri, timeout=self.timeout))
7574

7675
def get(self, uri, timeout=None):
7776
"""Perform a HTTP get
@@ -84,9 +83,9 @@ def get(self, uri, timeout=None):
8483
"""
8584
LOGGER.debug("GET %s", uri)
8685
try:
87-
return self._process_response(
88-
self.session.get(uri, timeout=timeout or self.timeout))
89-
except (requests.exceptions.ConnectionError,
86+
return api.Response(self.session.get(
87+
uri, timeout=timeout or self.timeout))
88+
except (requests.exceptions.RequestException,
9089
OSError, socket.error) as err:
9190
raise exceptions.RequestError(str(err))
9291

@@ -100,15 +99,12 @@ def get_stream(self, uri):
10099
LOGGER.debug("GET Stream from %s", uri)
101100
try:
102101
response = self.session.get(uri, stream=True)
103-
except (requests.exceptions.ConnectionError,
102+
except (requests.exceptions.RequestException,
104103
OSError, socket.error) as err:
105104
raise exceptions.RequestError(str(err))
106-
if response.encoding is None:
107-
response.encoding = 'utf-8'
108105
if utils.response_ok(response):
109-
for line in response.iter_lines():
110-
if line:
111-
yield line.decode('utf-8')
106+
for line in response.iter_lines(): # pragma: no cover
107+
yield line.decode('utf-8')
112108

113109
@prepare_data
114110
def put(self, uri, data=None, timeout=None):
@@ -127,31 +123,16 @@ def put(self, uri, data=None, timeout=None):
127123
if utils.is_string(data) else CONTENT_JSON
128124
}
129125
try:
130-
return self._process_response(
126+
return api.Response(
131127
self.session.put(
132128
uri, data=data, headers=headers,
133129
timeout=timeout or self.timeout))
134-
except (requests.exceptions.ConnectionError,
130+
except (requests.exceptions.RequestException,
135131
OSError, socket.error) as err:
136132
raise exceptions.RequestError(str(err))
137133

138-
@staticmethod
139-
def _process_response(response):
140-
"""Build an api.Response object based upon the requests response
141-
object.
142-
143-
:param requests.response response: The requests response
144-
:rtype: consulate.api.Response
145-
146-
"""
147-
try:
148-
return api.Response(
149-
response.status_code, response.content, response.headers)
150-
except (requests.exceptions.HTTPError, OSError, socket.error) as err:
151-
raise exceptions.RequestError(str(err))
152-
153134

154-
class UnixSocketRequest(Request):
135+
class UnixSocketRequest(Request): # pragma: no cover
155136
"""Use to communicate with Consul over a Unix socket"""
156137

157138
def __init__(self, timeout=None):

consulate/api/base.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import json
77
try:
88
from urllib.parse import urlencode # Python 3
9-
except ImportError: # pragma: no cover
9+
except ImportError:
1010
from urllib import urlencode # Python 2
1111

1212
from consulate import utils
@@ -106,7 +106,7 @@ def _put_no_response_body(self, url_parts, query=None, payload=None):
106106

107107
def _put_response_body(self, url_parts, query=None, payload=None):
108108
response = self._adapter.put(
109-
self._build_uri(url_parts, query), payload)
109+
self._build_uri(url_parts, query), data=payload)
110110
if utils.response_ok(response):
111111
return response.body
112112

@@ -123,17 +123,15 @@ class Response(object):
123123
body = None
124124
headers = None
125125

126-
def __init__(self, status_code, body, headers):
126+
def __init__(self, response):
127127
"""Create a new instance of the Response class.
128128
129-
:param int status_code: HTTP Status code
130-
:param str body: The response body
131-
:param dict headers: Response headers
129+
:param requests.response response: The requests response
132130
133131
"""
134-
self.status_code = status_code
135-
self.body = self._demarshal(body)
136-
self.headers = headers
132+
self.status_code = response.status_code
133+
self.body = self._demarshal(response.content)
134+
self.headers = response.headers
137135

138136
def _demarshal(self, body):
139137
"""Demarshal the request payload.

tests/acl_tests.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
import json
66
import uuid
77

8-
import consulate
98
import httmock
109

10+
import consulate
11+
from consulate import exceptions
12+
1113
from . import base
1214

1315
ACL_RULES = """key "" {
@@ -25,6 +27,16 @@ class TestCase(base.TestCase):
2527
def uuidv4():
2628
return str(uuid.uuid4())
2729

30+
def test_bootstrap_request_exception(self):
31+
32+
@httmock.all_requests
33+
def response_content(_url_unused, _request):
34+
raise OSError
35+
36+
with httmock.HTTMock(response_content):
37+
with self.assertRaises(exceptions.RequestError):
38+
self.consul.acl.bootstrap()
39+
2840
def test_bootstrap_success(self):
2941
expectation = self.uuidv4()
3042

@@ -96,6 +108,11 @@ def test_info_acl_id_not_found(self):
96108
with self.assertRaises(consulate.NotFound):
97109
self.forbidden_consul.acl.info(self.uuidv4())
98110

111+
def test_list_request_exception(self):
112+
with httmock.HTTMock(base.raise_oserror):
113+
with self.assertRaises(exceptions.RequestError):
114+
self.consul.acl.list()
115+
99116
def test_replication(self):
100117
result = self.forbidden_consul.acl.replication()
101118
self.assertFalse(result['Enabled'])

tests/agent_tests.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"""
55
import uuid
66

7+
import httmock
8+
79
import consulate
810
from consulate import utils
911
from consulate.models import agent
@@ -56,9 +58,17 @@ def test_metrics_forbidden(self):
5658
self.forbidden_consul.agent.metrics()
5759

5860
def test_monitor(self):
59-
for line in self.consul.agent.monitor():
61+
for offset, line in enumerate(self.consul.agent.monitor()):
6062
self.assertTrue(utils.is_string(line))
61-
break
63+
self.consul.agent.metrics()
64+
if offset > 1:
65+
break
66+
67+
def test_monitor_request_exception(self):
68+
with httmock.HTTMock(base.raise_oserror):
69+
with self.assertRaises(consulate.RequestError):
70+
for _line in self.consul.agent.monitor():
71+
break
6272

6373
def test_monitor_forbidden(self):
6474
with self.assertRaises(consulate.Forbidden):

tests/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import unittest
55
import uuid
66

7+
import httmock
8+
79
import consulate
810
from consulate import exceptions
911

@@ -21,6 +23,11 @@ def _decorator(self, *args, **kwargs):
2123
return _decorator
2224

2325

26+
@httmock.all_requests
27+
def raise_oserror(_url_unused, _request):
28+
raise OSError
29+
30+
2431
class TestCase(unittest.TestCase):
2532
def setUp(self):
2633
self.consul = consulate.Consul(

0 commit comments

Comments
 (0)