Skip to content

Commit

Permalink
Fix handling of missing psycopg2 module (#104)
Browse files Browse the repository at this point in the history
Execution of install_all_patches in the environment with no
psycopg2/psycopg2-binary leads to raising of an ImportError.

These changes also:

 - add test for missing modules handling
  • Loading branch information
Jamim authored and yurishkuro committed Sep 5, 2019
1 parent 32f3f88 commit 59bd920
Show file tree
Hide file tree
Showing 14 changed files with 53 additions and 26 deletions.
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from botocore.client import BaseClient
from botocore.exceptions import ClientError
from s3transfer.futures import BoundedExecutor
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_service_action_call = ServiceAction.__call__
Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from celery.signals import (
before_task_publish, task_prerun, task_success, task_failure
)
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_task_apply_async = Task.apply_async
Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/mysqldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# Try to save the original entry points
try:
import MySQLdb
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_MySQLdb_connect = MySQLdb.connect
Expand Down
4 changes: 2 additions & 2 deletions opentracing_instrumentation/client_hooks/psycopg2.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
# THE SOFTWARE.

from __future__ import absolute_import
from psycopg2.sql import Composable
from ._dbapi2 import ContextManagerConnectionWrapper as ConnectionWrapper
from ._dbapi2 import ConnectionFactory, CursorWrapper, NO_ARG
from ._singleton import singleton

# Try to save the original entry points
try:
import psycopg2.extensions
except ImportError: # pragma: no cover
from psycopg2.sql import Composable
except ImportError:
pass
else:
_psycopg2_connect = psycopg2.connect
Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
# Try to save the original entry points
try:
import requests.adapters
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_HTTPAdapter_send = requests.adapters.HTTPAdapter.send
Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
try:
from sqlalchemy.engine import Engine
from sqlalchemy import event
except ImportError: # pragma: no cover
except ImportError:
pass


Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/client_hooks/strict_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

try:
import redis
except ImportError: # pragma: no cover
except ImportError:
redis = None


Expand Down
12 changes: 6 additions & 6 deletions opentracing_instrumentation/client_hooks/tornado_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
# Try to save the original types for Tornado
try:
import tornado.simple_httpclient
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_SimpleAsyncHTTPClient_fetch_impl = \
Expand All @@ -51,7 +51,7 @@

try:
import tornado.curl_httpclient
except ImportError: # pragma: no cover
except ImportError:
pass
else:
_CurlAsyncHTTPClient_fetch_impl = \
Expand All @@ -74,7 +74,7 @@ def _build_patcher(obj, patched_attribute, replacement):
def _tornado():
try:
import tornado.simple_httpclient as simple
except ImportError: # pragma: no cover
except ImportError:
pass
else:
new_fetch_impl = traced_fetch_impl(
Expand All @@ -84,7 +84,7 @@ def _tornado():

try:
import tornado.curl_httpclient as curl
except ImportError: # pragma: no cover
except ImportError:
pass
else:
new_fetch_impl = traced_fetch_impl(
Expand All @@ -102,7 +102,7 @@ def install_patches():
def reset_patchers():
try:
import tornado.simple_httpclient as simple
except ImportError: # pragma: no cover
except ImportError:
pass
else:
setattr(
Expand All @@ -112,7 +112,7 @@ def reset_patchers():
)
try:
import tornado.curl_httpclient as curl
except ImportError: # pragma: no cover
except ImportError:
pass
else:
setattr(
Expand Down
2 changes: 1 addition & 1 deletion opentracing_instrumentation/http_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def before_request(request, tracer=None):
the global opentracing.tracer will be used.
:return: returns a new, already started span.
"""
if tracer is None: # pragma: no cover
if tracer is None:
tracer = opentracing.tracer

# we need to prepare tags upfront, mainly because RPC_SERVER tag must be
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ branch = True
omit =
setup.py
tests/*

[tool:pytest]
addopts = --cov=opentracing_instrumentation --cov-append -rs
4 changes: 0 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
],
extras_require={
'tests': [
# coveralls should be required before boto3
# to avoid dependency conflict for Python 2.7
'coveralls',

'boto3',
'botocore',
'celery',
Expand Down
5 changes: 3 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@

import opentracing
import pytest
from basictracer import BasicTracer
from basictracer.recorder import InMemoryRecorder
from opentracing.scope_managers.tornado import TornadoScopeManager


def _get_tracers(scope_manager=None):
from basictracer.recorder import InMemoryRecorder
from basictracer.tracer import BasicTracer

dummy_tracer = BasicTracer(recorder=InMemoryRecorder(),
scope_manager=scope_manager)
dummy_tracer.register_required_propagators()
Expand Down
20 changes: 20 additions & 0 deletions tests/opentracing_instrumentation/test_missing_modules_handling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
from importlib import import_module

import pytest

from opentracing_instrumentation.client_hooks import install_all_patches


HOOKS_WITH_PATCHERS = ('boto3', 'celery', 'mysqldb', 'sqlalchemy', 'requests')


@pytest.mark.skipif(os.environ.get('TEST_MISSING_MODULES_HANDLING') != '1',
reason='Not this time')
def test_missing_modules_handling():
install_all_patches()
for name in HOOKS_WITH_PATCHERS:
hook_module = import_module(
'opentracing_instrumentation.client_hooks.' + name
)
assert not hook_module.patcher.applicable
17 changes: 12 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
[tox]
envlist = py{27,35,36}-celery{3,4},py37-celery4
envlist =
py{27,35,36}-celery{3,4}
py37-celery4
py{27,35,36,37}-missing_modules
skip_missing_interpreters = true

[testenv]
setenv =
missing_modules: TEST_MISSING_MODULES_HANDLING=1
deps =
celery3: celery~=3.0
celery4: celery~=4.0
-rrequirements-test.txt
extras = tests
missing_modules: pytest-cov
extras =
!missing_modules: tests
commands =
flake8
pytest --cov=opentracing_instrumentation --cov-append -rs
!missing_modules: flake8
!missing_modules: pytest
missing_modules: pytest tests/opentracing_instrumentation/test_missing_modules_handling.py

0 comments on commit 59bd920

Please sign in to comment.