Skip to content

Commit

Permalink
[IMP] connector_carepoint: Add session reconnect handling
Browse files Browse the repository at this point in the history
* Add support to reconnect sessions on certain errors
* Bump `carepoint` lib version for `_init_env` method
  • Loading branch information
lasley committed Oct 25, 2016
1 parent 27a094d commit 9b92c9b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 5 deletions.
6 changes: 6 additions & 0 deletions connector_carepoint/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ def mock_adapter(unit):
yield API


class EndTestException(Exception):
""" It is a dummy Exception used to stop tests """
pass


class CarepointHelper(object):
""" Emulate a ConnectorEnvironment """

Expand Down Expand Up @@ -151,6 +156,7 @@ def setUp(self):
})
self.mock_api = mock_api
self.mock_adapter = mock_adapter
self.EndTestException = EndTestException

def get_carepoint_helper(self, model_name):
return CarepointHelper(
Expand Down
37 changes: 36 additions & 1 deletion connector_carepoint/tests/test_backend_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class TestBackendAdapter(SetUpCarepointBase):

def setUp(self):
super(TestBackendAdapter, self).setUp()
backend_adapter.carepoints = {}
self.Model = backend_adapter.CarepointCRUDAdapter

def _init_model(self, model='carepoint.carepoint.store'):
Expand Down Expand Up @@ -52,6 +51,42 @@ def test_init_assigns_instance(self):
res = self._init_model()
self.assertEqual(expect, res.carepoint)

def test_get_cp_model_resets(self):
""" It should guard a reconnectable exception and clear globals """
with self.mock_api():
model = self._init_model()
model.carepoint = mock.MagicMock()
model.carepoint.__getitem__.side_effect = [
model.RECONNECT_EXCEPTIONS[0],
]
model.carepoint._init_env.side_effect = self.EndTestException
with self.assertRaises(self.EndTestException):
model.search()

def test_get_cp_model_recurse(self):
""" It should recurse when reconnectable exception is identified """
with self.mock_api():
model = self._init_model()
model.carepoint = mock.MagicMock()
model.carepoint.__getitem__.side_effect = [
model.RECONNECT_EXCEPTIONS[0],
self.EndTestException,
]
with self.assertRaises(self.EndTestException):
model.search()

def test_get_cp_model_raise(self):
""" It should guard a reconnectable exception and clear globals """
with self.mock_api():
model = self._init_model()
model.carepoint = mock.MagicMock()
model.carepoint.__getitem__.side_effect = [
model.RECONNECT_EXCEPTIONS[0],
model.RECONNECT_EXCEPTIONS[0],
]
with self.assertRaises(model.RECONNECT_EXCEPTIONS[0]):
model.search()

def test_search_gets_pks(self):
""" It should get the primary keys of the db """
with self.mock_api() as api:
Expand Down
19 changes: 17 additions & 2 deletions connector_carepoint/unit/backend_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

from openerp.addons.connector.unit.backend_adapter import CRUDAdapter

try:
from sqlalchemy.exc import InvalidRequestError
except ImportError:
pass

try:
from carepoint import Carepoint
except ImportError:
Expand All @@ -13,6 +18,10 @@
class CarepointCRUDAdapter(CRUDAdapter):
""" External Records Adapter for Carepoint """

RECONNECT_EXCEPTIONS = [
InvalidRequestError,
]

def __init__(self, connector_env):
""" Ready the DB adapter
:param connector_env: current environment (backend, session, ...)
Expand All @@ -36,13 +45,19 @@ def __to_camel_case(self, snake_case):
parts = snake_case.split('_')
return "".join(x.title() for x in parts)

def __get_cp_model(self):
def __get_cp_model(self, retry=True):
""" Get the correct model object by name from Carepoint lib
:rtype: :class:`sqlalchemy.schema.Table`
"""
name = self.connector_env.model._cp_lib
camel_name = self.__to_camel_case(name)
return self.carepoint[camel_name]
try:
return self.carepoint[camel_name]
except tuple(self.RECONNECT_EXCEPTIONS):
if retry:
self.carepoint._init_env(True)
return self.__get_cp_model(False)
raise

def search(self, **filters):
""" Search table by filters and return record ids
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pint>=0.7.2
SQLAlchemy>=1.1.1
pysmb>=1.1.18
phonenumbers>=7.7.2
carepoint>=0.1.3.dev170
carepoint>=0.1.7
2 changes: 1 addition & 1 deletion test_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ xmlrunner>=1.7.7
pysmb>=1.1.18
pint>=0.7.2
phonenumbers>=7.7.2
carepoint>=0.1.3.dev170
carepoint>=0.1.7

0 comments on commit 9b92c9b

Please sign in to comment.