Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Update test environment and dependencies #81

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
language: python
matrix:
include:
- python: "2.7"
env: TEST_SUITE=suite_2_7 TOX_ENV=py27
- python: "pypy"
env: TEST_SUITE=suite_pypy TOX_ENV=pypy
- python: "3.4"
env: TEST_SUITE=suite_3_4 TOX_ENV=py34
- python: "pypy3"
env: TEST_SUITE=suite_pypy3 TOX_ENV=pypy3
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=pep8
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=docs
- python: "3.5"
env: TEST_SUITE=suite_3_4 TOX_ENV=py35
env: TEST_SUITE=suite_3_5 TOX_ENV=py35
- python: "3.7"
env: TEST_SUITE=suite_3_7 TOX_ENV=py37
- python: "3.8"
env: TEST_SUITE=suite_3_8 TOX_ENV=py38
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-httpretty
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-requests-mock
- python: "3.6"
env: TEST_SUITE=suite_3_4 TOX_ENV=py36
- python: "3.4"
env: TEST_SUITE=suite_3_4 TOX_ENV=pep8
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-responses
- python: "2.7"
env: TEST_SUITE=suite_2_7 TOX_ENV=docs
env: TEST_SUITE=suite_2_7 TOX_ENV=py27
- python: "2.7"
env: TEST_SUITE=suite_2_7 TOX_ENV=py27-httpretty
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-httpretty
- python: "2.7"
env: TEST_SUITE=suite_2_7 TOX_ENV=py27-requests-mock
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-requests-mock
- python: "2.7"
env: TEST_SUITE=suite_2_7 TOX_ENV=py27-responses
- python: "3.6"
env: TEST_SUITE=suite_3_6 TOX_ENV=py36-responses
- python: "pypy"
env: TEST_SUITE=suite_pypy TOX_ENV=pypy

sudo: required
before_install:
Expand Down
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ Out-of-the-box it supports the following frameworks:

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

.. note:: HTTPretty has some version and Python limitations. Version 0.8.6 works fine; however, version 0.9.x which supports
Python3 seems to have a breaking change that is causing problems. Only 0.8.6 is supported by StackInABox under Python2
for the time being. That is not to say you may not get it to work; just that the StackInABox Unit Tests cannot verify it
will work. PRs are welcome to help resolve this. See Issue #80 for status.

-----------
Error Codes
-----------
Expand Down
2 changes: 1 addition & 1 deletion stackinabox/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def request(self, method, request, uri, headers):
return self.try_handle_route(uri, method, request, uri, headers)

def sub_request(self, method, request, uri, headers):
"""Handle the supplied sub-service request on the specified routing URI.
"""Handle the supplied sub-service request on the specified routing URI

:param method: string - HTTP Verb
:param request: request object describing the HTTP request
Expand Down
44 changes: 37 additions & 7 deletions stackinabox/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,42 @@ class StackInABox(object):

"""

@classmethod
def get_thread_instance(cls):
"""
Interface to the thread storage to ensure the instance properly exists
"""
create = False

# if the `instance` property doesn't exist
if not hasattr(local_store, 'instance'):
local_store.instance = None
create = True

# if the instance doesn't exist at all
elif local_store.instance is None:
create = True

# if it's something else entirely...
elif not isinstance(local_store.instance, cls):
local_store.instance = None
create = True

# if the above conditions are met, create it
if create:
logger.debug('Creating new StackInABox instance...')
local_store.instance = cls()
logger.debug(
'Created StackInABox({0})'.format(local_store.instance.__id)
)

return local_store.instance

@classmethod
def reset_services(cls):
"""Reset the thread's StackInABox instance."""
logger.debug('Resetting services')
return local_store.instance.reset()
return cls.get_thread_instance().reset()

@classmethod
def register_service(cls, service):
Expand All @@ -51,7 +82,7 @@ def register_service(cls, service):

"""
logger.debug('Registering service {0}'.format(service.name))
return local_store.instance.register(service)
return cls.get_thread_instance().register(service)

@classmethod
def call_into(cls, method, request, uri, headers):
Expand All @@ -66,7 +97,7 @@ def call_into(cls, method, request, uri, headers):

"""
logger.debug('Request: {0} - {1}'.format(method, uri))
return local_store.instance.call(method,
return cls.get_thread_instance().call(method,
request,
uri,
headers)
Expand All @@ -85,7 +116,7 @@ def hold_onto(cls, name, obj):
"""
logger.debug('Holding on {0} of type {1} with id {2}'
.format(name, type(obj), id(obj)))
local_store.instance.into_hold(name, obj)
cls.get_thread_instance().into_hold(name, obj)

@classmethod
def hold_out(cls, name):
Expand All @@ -102,7 +133,7 @@ def hold_out(cls, name):
"""
logger.debug('Retreiving {0} from hold'
.format(name))
obj = local_store.instance.from_hold(name)
obj = cls.get_thread_instance().from_hold(name)
logger.debug('Retrieved {0} of type {1} with id {2} from hold'
.format(name, type(obj), id(obj)))
return obj
Expand All @@ -115,7 +146,7 @@ def update_uri(cls, uri):

"""
logger.debug('Request: Update URI to {0}'.format(uri))
local_store.instance.base_url = uri
cls.get_thread_instance().base_url = uri

def __init__(self):
"""Initialize the StackInABox instance.
Expand Down Expand Up @@ -307,4 +338,3 @@ def from_hold(self, name):

# Thread local instance of StackInABox
local_store = threading.local()
local_store.instance = StackInABox()
2 changes: 1 addition & 1 deletion stackinabox/util/httpretty/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def registration(uri):

# build the regex for the uri and register all http verbs
# with httpretty
regex = re.compile('(http)?s?(://)?{0}:?(\d+)?/'.format(uri),
regex = re.compile(r'(http)?s?(://)?{0}:?(\d+)?/'.format(uri),
re.I)
for method in HttpBaseClass.METHODS:
register_uri(method, regex, body=httpretty_callback)
Expand Down
6 changes: 5 additions & 1 deletion stackinabox/util/httpretty/decorator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"""
Stack-In-A-Box: HTTPretty Support via decorator
"""
import collections
try:
import collections.abc as collections
except ImportError:
# Py2.7 Support
import collections
import functools
import logging
import re
Expand Down
2 changes: 1 addition & 1 deletion stackinabox/util/requests_mock/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, uri):
:param uri: URI to match against
"""
self.regex = re.compile(
'(http)?s?(://)?{0}:?(\d+)?/'.format(uri), re.I)
r'(http)?s?(://)?{0}:?(\d+)?/'.format(uri), re.I)

def __call__(self, request):
"""object callable interface.
Expand Down
6 changes: 5 additions & 1 deletion stackinabox/util/requests_mock/decorator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"""
Stack-In-A-Box: Requests-Mock Support via Decorator
"""
import collections
try:
import collections.abc as collections
except ImportError:
# Py2.7 Support
import collections
import functools
import logging
import re
Expand Down
2 changes: 1 addition & 1 deletion stackinabox/util/responses/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def registration(uri):

# Build the regex for the URI and register all HTTP verbs
# with Responses
regex = re.compile('(http)?s?(://)?{0}:?(\d+)?/'.format(uri),
regex = re.compile(r'(http)?s?(://)?{0}:?(\d+)?/'.format(uri),
re.I)
METHODS = [
responses.DELETE,
Expand Down
7 changes: 6 additions & 1 deletion stackinabox/util/responses/decorator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""
Stack-In-A-Box: Responses Support via decorator
"""
import collections
try:
import collections.abc as collections
except ImportError:
# Py2.7 Support
import collections

import functools
import logging
import re
Expand Down
6 changes: 5 additions & 1 deletion stackinabox/util/tools/caseinsensitivedict.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import collections
try:
import collections.abc as collections
except ImportError:
# Py2.7 Support
import collections


# Compliments of Requests
Expand Down
17 changes: 8 additions & 9 deletions tests/test_service.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import re
import unittest

import httpretty
import requests

from stackinabox.stack import StackInABox
from stackinabox.services.service import *
import stackinabox.util.httpretty
import stackinabox.util.requests_mock


class TestServiceRegex(unittest.TestCase):
Expand Down Expand Up @@ -112,7 +111,6 @@ def test_bad_registration(self):
service.register(StackInABoxService.GET, '/',
AnotherAdvancedService.second_handler)

@httpretty.activate
def test_subservice_registration(self):
service = AnotherAdvancedService()
subservice = YetAnotherService()
Expand All @@ -121,10 +119,11 @@ def test_subservice_registration(self):

StackInABox.register_service(service)

stackinabox.util.httpretty.registration('localhost')
with stackinabox.util.requests_mock.activate():
stackinabox.util.requests_mock.registration('localhost')

res = requests.get('http://localhost/aas/french')
self.assertEqual(res.status_code,
200)
self.assertEqual(res.text,
'bonjour')
res = requests.get('http://localhost/aas/french')
self.assertEqual(res.status_code,
200)
self.assertEqual(res.text,
'bonjour')
11 changes: 5 additions & 6 deletions tests/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import unittest

import ddt
import httpretty
import requests

import stackinabox.util.httpretty
import stackinabox.util.requests_mock
from stackinabox.stack import (
StackInABox, ServiceAlreadyRegisteredError)
from stackinabox.services.service import *
Expand Down Expand Up @@ -52,12 +51,12 @@ def test_get_services_url(self, url, base, value):
result = StackInABox.get_services_url(url, base)
self.assertEqual(result, value)

@httpretty.activate
def test_service_exception(self):
exceptional = ExceptionalServices()
StackInABox.register_service(exceptional)

stackinabox.util.httpretty.registration('localhost')
with stackinabox.util.requests_mock.activate():
stackinabox.util.requests_mock.registration('localhost')

res = requests.get('http://localhost/except/')
self.assertEqual(res.status_code, 596)
res = requests.get('http://localhost/except/')
self.assertEqual(res.status_code, 596)
3 changes: 3 additions & 0 deletions tests/util/httpretty/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Stack-In-A-Box: Basic Test
"""
import logging
import sys
import unittest

import httpretty
Expand All @@ -18,6 +19,7 @@
logger = logging.getLogger(__name__)


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
@httpretty.activate
class TestHttprettyBasic(unittest.TestCase):

Expand All @@ -37,6 +39,7 @@ def test_basic(self):
self.assertEqual(res.text, 'Hello')


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
@httpretty.activate
class TestHttprettyAdvanced(unittest.TestCase):

Expand Down
5 changes: 5 additions & 0 deletions tests/util/httpretty/test_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Stack-In-A-Box: Basic Test
"""
import collections
import sys
import types
import unittest

Expand All @@ -13,6 +14,7 @@
from tests.utils.services import AdvancedService


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
class TestHttprettyBasicWithDecorator(unittest.TestCase):

@decorator.activate('localhost', HelloService())
Expand Down Expand Up @@ -41,6 +43,7 @@ def test_basic_with_stack_acccess(self, response_code, value='alpha',
self.assertIsInstance(stack[list(stack.keys())[0]], HelloService)


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
class TestHttprettyAdvancedWithDecorator(unittest.TestCase):

@decorator.activate('localhost', AdvancedService())
Expand Down Expand Up @@ -81,6 +84,7 @@ def httpretty_generator():
yield HelloService()


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
class TestHttprettyBasicWithDecoratorAndGenerator(unittest.TestCase):

def test_verify_generator(self):
Expand Down Expand Up @@ -127,6 +131,7 @@ def httpretty_list():
]


@unittest.skipIf(sys.version_info >= (3, 0), "Httpretty not supported by Py3")
class TestHttprettyBasicWithDecoratorAndList(unittest.TestCase):

def test_verify_list(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self):
self.register(StackInABoxService.GET, '/g',
AdvancedService.query_handler)
self.register(StackInABoxService.GET,
re.compile('^/\d+$'),
re.compile(r'^/\d+$'),
AdvancedService.regex_handler)

for key in self.POTENTIAL_RESPONSES.keys():
Expand Down
Loading