Skip to content

Commit d6c9a34

Browse files
committedMay 29, 2015
Merge pull request #35 from BenjamenMeyer/enhancement_errors_update
Enhancement errors update
2 parents d68fca6 + 9ca7915 commit d6c9a34

11 files changed

+124
-17
lines changed
 

‎README.rst

+10
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ Out-of-the-box it supports the following frameworks:
8989

9090
You can use any of them, and you must pull them in via your own test requirements.
9191

92+
-----------
93+
Error Codes
94+
-----------
95+
96+
StackInABox has some specific error codes to help with diagnosing issues:
97+
98+
- 597 - StackInABox - Base URL is correct, but service is unknown
99+
- 596 - StackInABox - Handling StackInABoxService generated an exception
100+
- 595 - StackInABoxService - Route Not handled
101+
92102
Both of these are extremely easy to use as shown in the following examples:
93103

94104
---------

‎setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ cover-package=stackinabox
66
cover-erase=1
77
cover-inclusive=true
88
cover-branches=true
9-
cover-min-percentage=83
9+
cover-min-percentage=88

‎stackinabox/services/service.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def __call__(self, method, request, uri, headers):
9696
request,
9797
uri,
9898
headers)
99-
else:
99+
elif self.obj is not None:
100100
logger.debug('Service Router ({0} - {1}): Located Subservice {2} '
101101
'on Route {3}. Calling...'
102102
.format(id(self),
@@ -109,6 +109,16 @@ def __call__(self, method, request, uri, headers):
109109
uri,
110110
headers)
111111

112+
else:
113+
logger.debug('Service Router ({0} - {1}): '
114+
'No Method handler for service'
115+
.format(id(self),
116+
self.service_name))
117+
return (405,
118+
headers,
119+
'{0} not supported. Supported Methods are {1}'.format(
120+
method, self.methods))
121+
112122

113123
class StackInABoxService(object):
114124
DELETE = 'DELETE'
@@ -236,7 +246,7 @@ def try_handle_route(self, route_uri, method, request, uri, headers):
236246
request,
237247
uri,
238248
headers)
239-
return (500, headers, 'Server Error')
249+
return (595, headers, 'Route ({0}) Not Handled'.format(uri))
240250

241251
def request(self, method, request, uri, headers):
242252
logger.debug('StackInABoxService ({0}:{1}): Request Received {2} - {3}'

‎stackinabox/stack.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def __get_service_url(base_url, service_name):
6969
return '{0}/{1}'.format(base_url, service_name)
7070

7171
@staticmethod
72-
def __get_services_url(url, base_url):
72+
def get_services_url(url, base_url):
7373
length = len(base_url)
7474
checks = ['http://', 'https://']
7575
for check in checks:
@@ -117,7 +117,7 @@ def register(self, service):
117117
if service.name not in self.services.keys():
118118
logger.debug('StackInABox({0}): Registering Service {1}'
119119
.format(self.__id, service.name))
120-
regex = '^/{0}'.format(service.name)
120+
regex = '^/{0}/'.format(service.name)
121121
self.services[service.name] = [
122122
re.compile(regex),
123123
service
@@ -133,7 +133,8 @@ def register(self, service):
133133
def call(self, method, request, uri, headers):
134134
logger.debug('StackInABox({0}): Received call to {1} - {2}'
135135
.format(self.__id, method, uri))
136-
service_uri = StackInABox.__get_services_url(uri, self.base_url)
136+
service_uri = StackInABox.get_services_url(uri, self.base_url)
137+
137138
for k, v in six.iteritems(self.services):
138139
matcher, service = v
139140
logger.debug('StackInABox({0}): Checking if Service {1} handles...'
@@ -155,10 +156,10 @@ def call(self, method, request, uri, headers):
155156
logger.exception('StackInABox({0}): Service {1} - '
156157
'Internal Failure'
157158
.format(self.__id, service.name))
158-
return (500,
159+
return (596,
159160
headers,
160161
'Service Handler had an error: {0}'.format(ex))
161-
return (500, headers, 'Unknown service')
162+
return (597, headers, 'Unknown service - {0}'.format(service_uri))
162163

163164
def into_hold(self, name, obj):
164165
logger.debug('StackInABox({0}): Holding onto {1} of type {2} '

‎stackinabox/tests/test_httpretty.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ def test_basic(self):
7373
self.assertEqual(res.text, 'okay')
7474

7575
res = requests.get('http://localhost/advanced/_234567890')
76-
self.assertEqual(res.status_code, 500)
76+
self.assertEqual(res.status_code, 595)
7777

7878
res = requests.put('http://localhost/advanced/h')
79-
self.assertEqual(res.status_code, 500)
79+
self.assertEqual(res.status_code, 405)
80+
81+
res = requests.put('http://localhost/advanced2/i')
82+
self.assertEqual(res.status_code, 597)

‎stackinabox/tests/test_requests_mock.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,13 @@ def test_basic(self):
8787
self.assertEqual(res.text, 'okay')
8888

8989
res = self.session.get('http://localhost/advanced/_234567890')
90-
self.assertEqual(res.status_code, 500)
90+
self.assertEqual(res.status_code, 595)
9191

9292
res = self.session.put('http://localhost/advanced/h')
93-
self.assertEqual(res.status_code, 500)
93+
self.assertEqual(res.status_code, 405)
94+
95+
res = self.session.put('http://localhost/advanced2/i')
96+
self.assertEqual(res.status_code, 597)
9497

9598
def test_context_requests_mock(self):
9699
with stackinabox.util_requests_mock.activate():

‎stackinabox/tests/test_responses.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
logger = logging.getLogger(__name__)
1919

2020

21-
@unittest.skipIf(six.PY3, 'Responses fails on PY3')
2221
def test_basic_responses():
2322

2423
@responses.activate
@@ -34,7 +33,6 @@ def run():
3433
run()
3534

3635

37-
@unittest.skipIf(six.PY3, 'Responses fails on PY3')
3836
def test_advanced_responses():
3937

4038
def run():
@@ -65,10 +63,13 @@ def run():
6563
assert res.text == 'okay'
6664

6765
res = requests.get('http://localhost/advanced/_234567890')
68-
assert res.status_code == 500
66+
assert res.status_code == 595
6967

7068
res = requests.put('http://localhost/advanced/h')
71-
assert res.status_code == 500
69+
assert res.status_code == 405
70+
71+
res = requests.put('http://localhost/advanced2/i')
72+
assert res.status_code == 597
7273

7374
StackInABox.reset_services()
7475

‎stackinabox/tests/test_stack.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import re
2+
import unittest
3+
4+
import ddt
5+
import httpretty
6+
import requests
7+
8+
import stackinabox.util_httpretty
9+
from stackinabox.stack import (
10+
StackInABox, ServiceAlreadyRegisteredError)
11+
from stackinabox.services.service import *
12+
from stackinabox.services.hello import HelloService
13+
14+
15+
class ExceptionalServices(StackInABoxService):
16+
17+
def __init__(self):
18+
super(ExceptionalServices, self).__init__('except')
19+
self.register(StackInABoxService.GET,
20+
'/',
21+
ExceptionalServices.handler)
22+
23+
def handler(self, request, uri, headers):
24+
raise Exception('Exceptional Service Failure')
25+
26+
27+
@ddt.ddt
28+
class TestStack(unittest.TestCase):
29+
30+
def setUp(self):
31+
super(TestStack, self).setUp()
32+
33+
def tearDown(self):
34+
super(TestStack, self).tearDown()
35+
StackInABox.reset_services()
36+
37+
def test_double_service_registration(self):
38+
service1 = HelloService()
39+
service2 = HelloService()
40+
41+
StackInABox.register_service(service1)
42+
with self.assertRaises(ServiceAlreadyRegisteredError):
43+
StackInABox.register_service(service2)
44+
45+
@ddt.data(
46+
('http://honeymoon/', 'honeymoon', '/'),
47+
('https://honeymoon/', 'honeymoon', '/'),
48+
('honeymoon/', 'honeymoon', '/')
49+
)
50+
@ddt.unpack
51+
def test_get_services_url(self, url, base, value):
52+
result = StackInABox.get_services_url(url, base)
53+
self.assertEqual(result, value)
54+
55+
@httpretty.activate
56+
def test_service_exception(self):
57+
exceptional = ExceptionalServices()
58+
StackInABox.register_service(exceptional)
59+
60+
stackinabox.util_httpretty.httpretty_registration('localhost')
61+
62+
res = requests.get('http://localhost/except/')
63+
self.assertEqual(res.status_code, 596)

‎stackinabox/tests/utils/services.py

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
from stackinabox.services.service import StackInABoxService
99

1010

11+
logger = logging.getLogger(__name__)
12+
13+
1114
class AdvancedService(StackInABoxService):
1215

1316
def __init__(self):

‎stackinabox/util_httpretty.py

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
from httpretty import register_uri
88
from httpretty.http import HttpBaseClass
9+
import httpretty.http
10+
import six
911

1012
from stackinabox.stack import StackInABox
1113
from stackinabox.utils import CaseInsensitiveDict
@@ -28,6 +30,16 @@ def httpretty_callback(request, uri, headers):
2830

2931

3032
def httpretty_registration(uri):
33+
34+
status_data = {
35+
595: 'StackInABoxService - Unknown Route',
36+
596: 'StackInABox - Exception in Service Handler',
37+
597: 'StackInABox - Unknown Service'
38+
}
39+
for k, v in six.iteritems(status_data):
40+
if k not in httpretty.http.STATUSES:
41+
httpretty.http.STATUSES[k] = v
42+
3143
logger.debug('Registering Stack-In-A-Box at {0} under Python HTTPretty'
3244
.format(uri))
3345
StackInABox.update_uri(uri)

‎tools/test-requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
coverage
2+
ddt
23
httpretty==0.8.6
34
nose
45
nose-exclude
56
pep8
67
requests
78
requests-mock
8-
responses
9+
responses>=0.4.0
910
six

0 commit comments

Comments
 (0)
Please sign in to comment.