Skip to content

Commit

Permalink
Merge pull request #8 from internap/handle-request-exceptions
Browse files Browse the repository at this point in the history
Added more Ubersmith exceptions
  • Loading branch information
fguillot committed Mar 31, 2016
2 parents 2e6ef8a + 6bf8f0a commit 1b77c12
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 109 deletions.
120 changes: 12 additions & 108 deletions tests/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from mock import patch, MagicMock
from hamcrest import assert_that, raises, calling
from mock import Mock
from requests.exceptions import ConnectionError, Timeout

from hamcrest import assert_that, equal_to, raises, calling

from tests.ubersmith_json.response_data_structure import a_response_data
import ubersmith_client
from ubersmith_client.exceptions import UbersmithConnectionError, UbersmithTimeout


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

self.auth = (self.username, self.password)
self.timeout = 60

@patch('ubersmith_client.ubersmith_request_get.requests')
def test_api_get_method_returns_without_arguments(self, requests_mock):
json_data = {
'company': 'council of ricks'
}
expected_call = self.expect_a_ubersmith_call(requests_mock=requests_mock,
method='client.list',
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
response = ubersmith_api.client.list()

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_get.requests')
def test_api_get_method_returns_with_arguments(self, request_mock):
json_data = {
'group_id': '1',
'client_id': '30001',
'assignment_count': '1'
}
expected_call = self.expect_a_ubersmith_call(requests_mock=request_mock,
method='device.ip_group_list',
fac_id=1,
client_id=30001,
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_post_method_returns_with_arguments(self, request_mock):
json_data = {
'group_id': '1',
'client_id': '30001',
'assignment_count': '1'
}
expected_call = self.expect_a_ubersmith_call_post(requests_mock=request_mock,
method='device.ip_group_list',
fac_id=1,
client_id=30001,
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_post_method_returns_without_arguments(self, requests_mock):
json_data = {
'company': 'schwifty'
}
expected_call = self.expect_a_ubersmith_call_post(requests_mock=requests_mock,
method='client.list',
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)
response = ubersmith_api.client.list()

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_raises_exception_with_if_data_status_is_false(self, requests_mock):
data = a_response_data(status=False,
error_code=1,
error_message='invalid method specified: client.miss',
data="schwifty")
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False)

self.expect_a_ubersmith_call_post(requests_mock, method='client.miss', returning=data)
assert_that(calling(ubersmith_api.client.miss), raises(ubersmith_client.exceptions.UbersmithException))

def expect_a_ubersmith_call(self, requests_mock, returning=None, **kwargs):
response = MagicMock(status_code=200)
requests_mock.get = MagicMock(return_value=response)
response.json = MagicMock(return_value=returning)

def assert_called_with():
requests_mock.get.assert_called_with(auth=self.auth, params=kwargs, timeout=self.timeout, url=self.url)
response.json.assert_called_with()

return assert_called_with
def test_api_method_returns_handle_connection_error_exception(self):
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
ubersmith_api.ubersmith_request = Mock(side_effect=ConnectionError())

def expect_a_ubersmith_call_post(self, requests_mock, returning=None, status_code=200, **kwargs):
response = MagicMock(status_code=status_code)
requests_mock.post = MagicMock(return_value=response)
response.json = MagicMock(return_value=returning)
assert_that(calling(ubersmith_api.__getattr__).with_args("client"), raises(UbersmithConnectionError))

def assert_called_with():
requests_mock.post.assert_called_with(auth=self.auth, timeout=self.timeout, url=self.url, data=kwargs)
response.json.assert_called_with()
def test_api_method_returns_handle_timeout_exception(self):
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
ubersmith_api.ubersmith_request = Mock(side_effect=Timeout())

return assert_called_with
assert_that(calling(ubersmith_api.__getattr__).with_args("client"), raises(UbersmithTimeout))
76 changes: 76 additions & 0 deletions tests/ubersmith_request_get_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright 2016 Internap.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from hamcrest import assert_that, equal_to
from mock import patch, MagicMock

import ubersmith_client
from tests.ubersmith_json.response_data_structure import a_response_data


class UbersmithRequestGetTest(unittest.TestCase):
def setUp(self):
self.url = 'http://ubersmith.example.com/'
self.username = 'admin'
self.password = 'test'

self.auth = (self.username, self.password)
self.timeout = 60

@patch('ubersmith_client.ubersmith_request_get.requests')
def test_api_get_method_returns_without_arguments(self, requests_mock):
json_data = {
'company': 'council of ricks'
}
expected_call = self.expect_a_ubersmith_call(requests_mock=requests_mock,
method='client.list',
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
response = ubersmith_api.client.list()

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_get.requests')
def test_api_get_method_returns_with_arguments(self, request_mock):
json_data = {
'group_id': '1',
'client_id': '30001',
'assignment_count': '1'
}
expected_call = self.expect_a_ubersmith_call(requests_mock=request_mock,
method='device.ip_group_list',
fac_id=1,
client_id=30001,
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True)
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)

assert_that(response, equal_to(json_data))

expected_call()

def expect_a_ubersmith_call(self, requests_mock, returning=None, **kwargs):
response = MagicMock(status_code=200)
requests_mock.get = MagicMock(return_value=response)
response.json = MagicMock(return_value=returning)

def assert_called_with():
requests_mock.get.assert_called_with(auth=self.auth, params=kwargs, timeout=self.timeout, url=self.url)
response.json.assert_called_with()

return assert_called_with
87 changes: 87 additions & 0 deletions tests/ubersmith_request_post_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Copyright 2016 Internap.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from hamcrest import assert_that, equal_to, calling, raises
from mock import patch, MagicMock

import ubersmith_client
from tests.ubersmith_json.response_data_structure import a_response_data


class UbersmithRequestPostTest(unittest.TestCase):
def setUp(self):
self.url = 'http://ubersmith.example.com/'
self.username = 'admin'
self.password = 'test'

self.auth = (self.username, self.password)
self.timeout = 60

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_post_method_returns_with_arguments(self, request_mock):
json_data = {
'group_id': '1',
'client_id': '30001',
'assignment_count': '1'
}
expected_call = self.expect_a_ubersmith_call_post(requests_mock=request_mock,
method='device.ip_group_list',
fac_id=1,
client_id=30001,
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001)

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_post_method_returns_without_arguments(self, requests_mock):
json_data = {
'company': 'schwifty'
}
expected_call = self.expect_a_ubersmith_call_post(requests_mock=requests_mock,
method='client.list',
returning=a_response_data(data=json_data))

ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)
response = ubersmith_api.client.list()

assert_that(response, equal_to(json_data))

expected_call()

@patch('ubersmith_client.ubersmith_request_post.requests')
def test_api_raises_exception_with_if_data_status_is_false(self, requests_mock):
data = a_response_data(status=False,
error_code=1,
error_message='invalid method specified: client.miss',
data="schwifty")
ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password)

self.expect_a_ubersmith_call_post(requests_mock, method='client.miss', returning=data)
assert_that(calling(ubersmith_api.client.miss), raises(ubersmith_client.exceptions.UbersmithException))

def expect_a_ubersmith_call_post(self, requests_mock, returning=None, status_code=200, **kwargs):
response = MagicMock(status_code=status_code)
requests_mock.post = MagicMock(return_value=response)
response.json = MagicMock(return_value=returning)

def assert_called_with():
requests_mock.post.assert_called_with(auth=self.auth, timeout=self.timeout, url=self.url, data=kwargs)
response.json.assert_called_with()

return assert_called_with
11 changes: 11 additions & 0 deletions ubersmith_client/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ def __init__(self):
class UnknownError(UbersmithException):
def __init__(self, code):
super(UnknownError, self).__init__(code=code, message='An unknown error occurred')


class UbersmithConnectionError(UbersmithException):
def __init__(self, url):
super(UbersmithConnectionError, self).__init__(message="Could not connect to {0}".format(url))


class UbersmithTimeout(UbersmithException):
def __init__(self, url, timeout):
super(UbersmithTimeout, self)\
.__init__(message='Trying to connect to {url} times out after {timeout}'.format(url=url, timeout=timeout))
10 changes: 9 additions & 1 deletion ubersmith_client/ubersmith_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from requests.exceptions import ConnectionError, Timeout

from ubersmith_client.exceptions import UbersmithConnectionError, UbersmithTimeout
from ubersmith_client.ubersmith_request_get import UbersmithRequestGet
from ubersmith_client.ubersmith_request_post import UbersmithRequestPost

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

def __getattr__(self, module):
return self.ubersmith_request(self.url, self.user, self.password, module, self.timeout)
try:
return self.ubersmith_request(self.url, self.user, self.password, module, self.timeout)
except ConnectionError:
raise UbersmithConnectionError(self.url)
except Timeout:
raise UbersmithTimeout(self.url, self.timeout)

0 comments on commit 1b77c12

Please sign in to comment.