Skip to content

Commit 1b77c12

Browse files
committed
Merge pull request #8 from internap/handle-request-exceptions
Added more Ubersmith exceptions
2 parents 2e6ef8a + 6bf8f0a commit 1b77c12

File tree

5 files changed

+195
-109
lines changed

5 files changed

+195
-109
lines changed

tests/api_test.py

Lines changed: 12 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import unittest
15-
from mock import patch, MagicMock
15+
from hamcrest import assert_that, raises, calling
16+
from mock import Mock
17+
from requests.exceptions import ConnectionError, Timeout
1618

17-
from hamcrest import assert_that, equal_to, raises, calling
18-
19-
from tests.ubersmith_json.response_data_structure import a_response_data
2019
import ubersmith_client
20+
from ubersmith_client.exceptions import UbersmithConnectionError, UbersmithTimeout
2121

2222

2323
class ApiTest(unittest.TestCase):
@@ -26,110 +26,14 @@ def setUp(self):
2626
self.username = 'admin'
2727
self.password = 'test'
2828

29-
self.auth = (self.username, self.password)
30-
self.timeout = 60
31-
32-
@patch('ubersmith_client.ubersmith_request_get.requests')
33-
def test_api_get_method_returns_without_arguments(self, requests_mock):
34-
json_data = {
35-
'company': 'council of ricks'
36-
}
37-
expected_call = self.expect_a_ubersmith_call(requests_mock=requests_mock,
38-
method='client.list',
39-
returning=a_response_data(data=json_data))
40-
41-
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
42-
response = ubersmith_api.client.list()
43-
44-
assert_that(response, equal_to(json_data))
45-
46-
expected_call()
47-
48-
@patch('ubersmith_client.ubersmith_request_get.requests')
49-
def test_api_get_method_returns_with_arguments(self, request_mock):
50-
json_data = {
51-
'group_id': '1',
52-
'client_id': '30001',
53-
'assignment_count': '1'
54-
}
55-
expected_call = self.expect_a_ubersmith_call(requests_mock=request_mock,
56-
method='device.ip_group_list',
57-
fac_id=1,
58-
client_id=30001,
59-
returning=a_response_data(data=json_data))
60-
61-
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
62-
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)
63-
64-
assert_that(response, equal_to(json_data))
65-
66-
expected_call()
67-
68-
@patch('ubersmith_client.ubersmith_request_post.requests')
69-
def test_api_post_method_returns_with_arguments(self, request_mock):
70-
json_data = {
71-
'group_id': '1',
72-
'client_id': '30001',
73-
'assignment_count': '1'
74-
}
75-
expected_call = self.expect_a_ubersmith_call_post(requests_mock=request_mock,
76-
method='device.ip_group_list',
77-
fac_id=1,
78-
client_id=30001,
79-
returning=a_response_data(data=json_data))
80-
81-
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)
82-
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)
83-
84-
assert_that(response, equal_to(json_data))
85-
86-
expected_call()
87-
88-
@patch('ubersmith_client.ubersmith_request_post.requests')
89-
def test_api_post_method_returns_without_arguments(self, requests_mock):
90-
json_data = {
91-
'company': 'schwifty'
92-
}
93-
expected_call = self.expect_a_ubersmith_call_post(requests_mock=requests_mock,
94-
method='client.list',
95-
returning=a_response_data(data=json_data))
96-
97-
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)
98-
response = ubersmith_api.client.list()
99-
100-
assert_that(response, equal_to(json_data))
101-
102-
expected_call()
103-
104-
@patch('ubersmith_client.ubersmith_request_post.requests')
105-
def test_api_raises_exception_with_if_data_status_is_false(self, requests_mock):
106-
data = a_response_data(status=False,
107-
error_code=1,
108-
error_message='invalid method specified: client.miss',
109-
data="schwifty")
110-
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)
111-
112-
self.expect_a_ubersmith_call_post(requests_mock, method='client.miss', returning=data)
113-
assert_that(calling(ubersmith_api.client.miss), raises(ubersmith_client.exceptions.UbersmithException))
114-
115-
def expect_a_ubersmith_call(self, requests_mock, returning=None, **kwargs):
116-
response = MagicMock(status_code=200)
117-
requests_mock.get = MagicMock(return_value=response)
118-
response.json = MagicMock(return_value=returning)
119-
120-
def assert_called_with():
121-
requests_mock.get.assert_called_with(auth=self.auth, params=kwargs, timeout=self.timeout, url=self.url)
122-
response.json.assert_called_with()
123-
124-
return assert_called_with
29+
def test_api_method_returns_handle_connection_error_exception(self):
30+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
31+
ubersmith_api.ubersmith_request = Mock(side_effect=ConnectionError())
12532

126-
def expect_a_ubersmith_call_post(self, requests_mock, returning=None, status_code=200, **kwargs):
127-
response = MagicMock(status_code=status_code)
128-
requests_mock.post = MagicMock(return_value=response)
129-
response.json = MagicMock(return_value=returning)
33+
assert_that(calling(ubersmith_api.__getattr__).with_args("client"), raises(UbersmithConnectionError))
13034

131-
def assert_called_with():
132-
requests_mock.post.assert_called_with(auth=self.auth, timeout=self.timeout, url=self.url, data=kwargs)
133-
response.json.assert_called_with()
35+
def test_api_method_returns_handle_timeout_exception(self):
36+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
37+
ubersmith_api.ubersmith_request = Mock(side_effect=Timeout())
13438

135-
return assert_called_with
39+
assert_that(calling(ubersmith_api.__getattr__).with_args("client"), raises(UbersmithTimeout))
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright 2016 Internap.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import unittest
15+
from hamcrest import assert_that, equal_to
16+
from mock import patch, MagicMock
17+
18+
import ubersmith_client
19+
from tests.ubersmith_json.response_data_structure import a_response_data
20+
21+
22+
class UbersmithRequestGetTest(unittest.TestCase):
23+
def setUp(self):
24+
self.url = 'http://ubersmith.example.com/'
25+
self.username = 'admin'
26+
self.password = 'test'
27+
28+
self.auth = (self.username, self.password)
29+
self.timeout = 60
30+
31+
@patch('ubersmith_client.ubersmith_request_get.requests')
32+
def test_api_get_method_returns_without_arguments(self, requests_mock):
33+
json_data = {
34+
'company': 'council of ricks'
35+
}
36+
expected_call = self.expect_a_ubersmith_call(requests_mock=requests_mock,
37+
method='client.list',
38+
returning=a_response_data(data=json_data))
39+
40+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
41+
response = ubersmith_api.client.list()
42+
43+
assert_that(response, equal_to(json_data))
44+
45+
expected_call()
46+
47+
@patch('ubersmith_client.ubersmith_request_get.requests')
48+
def test_api_get_method_returns_with_arguments(self, request_mock):
49+
json_data = {
50+
'group_id': '1',
51+
'client_id': '30001',
52+
'assignment_count': '1'
53+
}
54+
expected_call = self.expect_a_ubersmith_call(requests_mock=request_mock,
55+
method='device.ip_group_list',
56+
fac_id=1,
57+
client_id=30001,
58+
returning=a_response_data(data=json_data))
59+
60+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
61+
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)
62+
63+
assert_that(response, equal_to(json_data))
64+
65+
expected_call()
66+
67+
def expect_a_ubersmith_call(self, requests_mock, returning=None, **kwargs):
68+
response = MagicMock(status_code=200)
69+
requests_mock.get = MagicMock(return_value=response)
70+
response.json = MagicMock(return_value=returning)
71+
72+
def assert_called_with():
73+
requests_mock.get.assert_called_with(auth=self.auth, params=kwargs, timeout=self.timeout, url=self.url)
74+
response.json.assert_called_with()
75+
76+
return assert_called_with
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright 2016 Internap.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import unittest
15+
from hamcrest import assert_that, equal_to, calling, raises
16+
from mock import patch, MagicMock
17+
18+
import ubersmith_client
19+
from tests.ubersmith_json.response_data_structure import a_response_data
20+
21+
22+
class UbersmithRequestPostTest(unittest.TestCase):
23+
def setUp(self):
24+
self.url = 'http://ubersmith.example.com/'
25+
self.username = 'admin'
26+
self.password = 'test'
27+
28+
self.auth = (self.username, self.password)
29+
self.timeout = 60
30+
31+
@patch('ubersmith_client.ubersmith_request_post.requests')
32+
def test_api_post_method_returns_with_arguments(self, request_mock):
33+
json_data = {
34+
'group_id': '1',
35+
'client_id': '30001',
36+
'assignment_count': '1'
37+
}
38+
expected_call = self.expect_a_ubersmith_call_post(requests_mock=request_mock,
39+
method='device.ip_group_list',
40+
fac_id=1,
41+
client_id=30001,
42+
returning=a_response_data(data=json_data))
43+
44+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
45+
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)
46+
47+
assert_that(response, equal_to(json_data))
48+
49+
expected_call()
50+
51+
@patch('ubersmith_client.ubersmith_request_post.requests')
52+
def test_api_post_method_returns_without_arguments(self, requests_mock):
53+
json_data = {
54+
'company': 'schwifty'
55+
}
56+
expected_call = self.expect_a_ubersmith_call_post(requests_mock=requests_mock,
57+
method='client.list',
58+
returning=a_response_data(data=json_data))
59+
60+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
61+
response = ubersmith_api.client.list()
62+
63+
assert_that(response, equal_to(json_data))
64+
65+
expected_call()
66+
67+
@patch('ubersmith_client.ubersmith_request_post.requests')
68+
def test_api_raises_exception_with_if_data_status_is_false(self, requests_mock):
69+
data = a_response_data(status=False,
70+
error_code=1,
71+
error_message='invalid method specified: client.miss',
72+
data="schwifty")
73+
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
74+
75+
self.expect_a_ubersmith_call_post(requests_mock, method='client.miss', returning=data)
76+
assert_that(calling(ubersmith_api.client.miss), raises(ubersmith_client.exceptions.UbersmithException))
77+
78+
def expect_a_ubersmith_call_post(self, requests_mock, returning=None, status_code=200, **kwargs):
79+
response = MagicMock(status_code=status_code)
80+
requests_mock.post = MagicMock(return_value=response)
81+
response.json = MagicMock(return_value=returning)
82+
83+
def assert_called_with():
84+
requests_mock.post.assert_called_with(auth=self.auth, timeout=self.timeout, url=self.url, data=kwargs)
85+
response.json.assert_called_with()
86+
87+
return assert_called_with

ubersmith_client/exceptions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@ def __init__(self):
6060
class UnknownError(UbersmithException):
6161
def __init__(self, code):
6262
super(UnknownError, self).__init__(code=code, message='An unknown error occurred')
63+
64+
65+
class UbersmithConnectionError(UbersmithException):
66+
def __init__(self, url):
67+
super(UbersmithConnectionError, self).__init__(message="Could not connect to {0}".format(url))
68+
69+
70+
class UbersmithTimeout(UbersmithException):
71+
def __init__(self, url, timeout):
72+
super(UbersmithTimeout, self)\
73+
.__init__(message='Trying to connect to {url} times out after {timeout}'.format(url=url, timeout=timeout))

ubersmith_client/ubersmith_api.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
13+
from requests.exceptions import ConnectionError, Timeout
14+
15+
from ubersmith_client.exceptions import UbersmithConnectionError, UbersmithTimeout
1316
from ubersmith_client.ubersmith_request_get import UbersmithRequestGet
1417
from ubersmith_client.ubersmith_request_post import UbersmithRequestPost
1518

@@ -23,4 +26,9 @@ def __init__(self, url, user, password, timeout, use_http_get):
2326
self.ubersmith_request = UbersmithRequestGet if use_http_get else UbersmithRequestPost
2427

2528
def __getattr__(self, module):
26-
return self.ubersmith_request(self.url, self.user, self.password, module, self.timeout)
29+
try:
30+
return self.ubersmith_request(self.url, self.user, self.password, module, self.timeout)
31+
except ConnectionError:
32+
raise UbersmithConnectionError(self.url)
33+
except Timeout:
34+
raise UbersmithTimeout(self.url, self.timeout)

0 commit comments

Comments
 (0)