Skip to content

Commit 91daa63

Browse files
dray92black-adder
authored andcommitted
Add function to install interceptors from list (#36)
1 parent cb72097 commit 91daa63

File tree

3 files changed

+93
-8
lines changed

3 files changed

+93
-8
lines changed

opentracing_instrumentation/client_hooks/__init__.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@
1919
# THE SOFTWARE.
2020
from __future__ import absolute_import
2121

22+
from collections import Sequence
23+
2224
import importlib
2325
import logging
2426

27+
import six
28+
2529

2630
def install_all_patches():
2731
"""
@@ -60,14 +64,38 @@ def install_patches(patchers='all'):
6064
if patchers is None or patchers == 'all':
6165
install_all_patches()
6266
return
63-
if type(patchers) is list:
64-
for patch_func_name in patchers:
65-
logging.info('Loading client hook %s', patch_func_name)
66-
patch_func = _load_symbol(patch_func_name)
67-
logging.info('Applying client hook %s', patch_func_name)
68-
patch_func()
69-
return
70-
raise ValueError('patchers argument must be None, "all", or a list')
67+
if not _valid_args(patchers):
68+
raise ValueError('patchers argument must be None, "all", or a list')
69+
70+
for patch_func_name in patchers:
71+
logging.info('Loading client hook %s', patch_func_name)
72+
patch_func = _load_symbol(patch_func_name)
73+
logging.info('Applying client hook %s', patch_func_name)
74+
patch_func()
75+
76+
77+
def install_client_interceptors(client_interceptors=()):
78+
"""
79+
Install client interceptors for the patchers.
80+
81+
:param client_interceptors: a list of client interceptors to install.
82+
Should be a list of classes
83+
"""
84+
if not _valid_args(client_interceptors):
85+
raise ValueError('client_interceptors argument must be a list')
86+
87+
from ..http_client import ClientInterceptors
88+
89+
for client_interceptor in client_interceptors:
90+
logging.info('Loading client interceptor %s', client_interceptor)
91+
interceptor_class = _load_symbol(client_interceptor)
92+
logging.info('Adding client interceptor %s', client_interceptor)
93+
ClientInterceptors.append(interceptor_class())
94+
95+
96+
def _valid_args(value):
97+
return isinstance(value, Sequence) and \
98+
not isinstance(value, six.string_types)
7199

72100

73101
def _load_symbol(name):

tests/opentracing_instrumentation/__init__.py

Whitespace-only changes.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright (c) 2017 Uber Technologies, Inc.
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
from __future__ import absolute_import
21+
22+
from mock import patch
23+
import pytest
24+
25+
from opentracing_instrumentation.client_hooks import install_client_interceptors
26+
from opentracing_instrumentation.interceptors import OpenTracingInterceptor
27+
28+
29+
class TestClientInterceptor(OpenTracingInterceptor):
30+
31+
def process(self, request, span):
32+
pass
33+
34+
35+
def Any(cls):
36+
37+
class Any(cls):
38+
39+
def __eq__(self, other):
40+
return isinstance(other, cls)
41+
42+
return Any()
43+
44+
45+
def test_install_client_interceptors_non_list_arg():
46+
with pytest.raises(ValueError):
47+
install_client_interceptors('abc')
48+
49+
50+
def test_install_client_interceptors():
51+
# TODO: can this path be obtained programmatically?
52+
path_to_interceptor = ('tests.opentracing_instrumentation.'
53+
'test_install_client_hooks.TestClientInterceptor')
54+
with patch('opentracing_instrumentation.http_client.ClientInterceptors') as MockClientInterceptors:
55+
install_client_interceptors([path_to_interceptor])
56+
57+
MockClientInterceptors.append.assert_called_once_with(Any(TestClientInterceptor))

0 commit comments

Comments
 (0)