From 036443d020aa42e0f9352fadcd0d9e47ea0c11a5 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Tue, 30 Jul 2019 11:52:02 -0700 Subject: [PATCH 1/9] we dont need thread locks --- .../azure-core/azure/core/tracing/context.py | 38 +++++-------------- .../azure-core/tests/test_tracing_context.py | 11 ++---- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/sdk/core/azure-core/azure/core/tracing/context.py b/sdk/core/azure-core/azure/core/tracing/context.py index a00f88f2d854..f8761cd71502 100644 --- a/sdk/core/azure-core/azure/core/tracing/context.py +++ b/sdk/core/azure-core/azure/core/tracing/context.py @@ -29,8 +29,8 @@ class ContextProtocol(Protocol): Implements set and get variables in a thread safe way. """ - def __init__(self, name, default, lock): - # type: (string, Any, threading.Lock) -> None + def __init__(self, name, default): + # type: (string, Any) -> None pass def clear(self): @@ -54,11 +54,10 @@ class _AsyncContext(object): Uses contextvars to set and get variables globally in a thread safe way. """ - def __init__(self, name, default, lock): + def __init__(self, name, default): self.name = name self.contextvar = contextvars.ContextVar(name) self.default = default if callable(default) else (lambda: default) - self.lock = lock def clear(self): # type: () -> None @@ -78,8 +77,7 @@ def get(self): def set(self, value): # type: (Any) -> None """Set the value in the context.""" - with self.lock: - self.contextvar.set(value) + self.contextvar.set(value) class _ThreadLocalContext(object): @@ -88,11 +86,10 @@ class _ThreadLocalContext(object): """ _thread_local = threading.local() - def __init__(self, name, default, lock): - # type: (str, Any, threading.Lock) -> None + def __init__(self, name, default): + # type: (str, Any) -> None self.name = name self.default = default if callable(default) else (lambda: default) - self.lock = lock def clear(self): # type: () -> None @@ -112,16 +109,14 @@ def get(self): def set(self, value): # type: (Any) -> None """Set the value in the context.""" - with self.lock: - setattr(self._thread_local, self.name, value) + setattr(self._thread_local, self.name, value) -class TracingContext: - _lock = threading.Lock() - +class TracingContext(object): def __init__(self): # type: () -> None - self.current_span = TracingContext._get_context_class("current_span", None) + context_class = _AsyncContext if contextvars else _ThreadLocalContext + self.current_span = context_class("current_span", None) def with_current_context(self, func): # type: (Callable[[Any], Any]) -> Any @@ -146,17 +141,4 @@ def call_with_current_context(*args, **kwargs): return call_with_current_context - @classmethod - def _get_context_class(cls, name, default_val): - # type: (str, Any) -> ContextProtocol - """ - Returns an instance of the the context class that stores the variable. - :param name: The key to store the variable in the context class - :param default_val: The default value of the variable if unset - :return: An instance that implements the context protocol class - """ - context_class = _AsyncContext if contextvars else _ThreadLocalContext - return context_class(name, default_val, cls._lock) - - tracing_context = TracingContext() diff --git a/sdk/core/azure-core/tests/test_tracing_context.py b/sdk/core/azure-core/tests/test_tracing_context.py index 59aa2c8a8b60..984d2ad480d3 100644 --- a/sdk/core/azure-core/tests/test_tracing_context.py +++ b/sdk/core/azure-core/tests/test_tracing_context.py @@ -34,19 +34,14 @@ def __exit__(self, exc_type, exc_val, exc_tb): class TestContext(unittest.TestCase): - def test_get_context_class(self): - with ContextHelper(): - slot = tracing_context._get_context_class("temp", 1) - assert slot.get() == 1 - slot.set(2) - assert slot.get() == 2 - def test_current_span(self): with ContextHelper(): - assert tracing_context.current_span.get() is None + assert not tracing_context.current_span.get() val = mock.Mock(spec=AbstractSpan) tracing_context.current_span.set(val) assert tracing_context.current_span.get() == val + tracing_context.current_span.clear() + assert not tracing_context.current_span.get() def test_with_current_context(self): with ContextHelper(tracer_to_use=mock.Mock(AbstractSpan)): From d6887e7b6cd6955d1f625c2e550731b3351c2ed0 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Tue, 30 Jul 2019 16:55:57 -0700 Subject: [PATCH 2/9] add contextvars --- sdk/core/azure-core/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/core/azure-core/setup.py b/sdk/core/azure-core/setup.py index bdab06be195c..b11c543fcda0 100644 --- a/sdk/core/azure-core/setup.py +++ b/sdk/core/azure-core/setup.py @@ -62,6 +62,7 @@ ]), install_requires=[ 'requests>=2.18.4', + 'contextvars>=3.5' ], extras_require={ ":python_version<'3.0'": ['azure-nspkg'], From ce2904c1d77efd8dcb09648081b2c26c517a72b6 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Tue, 30 Jul 2019 17:11:42 -0700 Subject: [PATCH 3/9] fix version stuff --- sdk/core/azure-core/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/azure-core/setup.py b/sdk/core/azure-core/setup.py index b11c543fcda0..e5bbaebb52c5 100644 --- a/sdk/core/azure-core/setup.py +++ b/sdk/core/azure-core/setup.py @@ -62,9 +62,9 @@ ]), install_requires=[ 'requests>=2.18.4', - 'contextvars>=3.5' ], extras_require={ ":python_version<'3.0'": ['azure-nspkg'], + ":python_version>='3.5'": ['contextvars'], } ) From 1b688260be06d39ff3593b615cd780297e35f87a Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Wed, 31 Jul 2019 13:51:22 -0700 Subject: [PATCH 4/9] mypy fixes --- .../azure-core/azure/core/tracing/common.py | 20 +++++++++++++++-- .../azure-core/azure/core/tracing/context.py | 11 ++++++---- .../azure/core/tracing/decorator.py | 22 ++++++++++++++----- .../azure/core/tracing/decorator_async.py | 22 ++++++++++++++----- .../azure/core/tracing/ext/opencensus_span.py | 2 +- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/sdk/core/azure-core/azure/core/tracing/common.py b/sdk/core/azure-core/azure/core/tracing/common.py index b0e425a14d10..8b024cf1d105 100644 --- a/sdk/core/azure-core/azure/core/tracing/common.py +++ b/sdk/core/azure-core/azure/core/tracing/common.py @@ -36,11 +36,27 @@ TYPE_CHECKING = False if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any, Optional, Union, Callable + + +def get_function_and_class_name(func, *args): + # type: (Callable, List[Any]) -> str + """ + Given a function and its unamed arguments, returns class_name.function_name. It assumes the first argument + is `self`. If there are no arguments then it only returns the function name. + + :param func: the function passed in + :type func: `collections.abc.Callable` + :param args: List of arguments passed into the function + :type args: List[Any] + """ + if args: + return "{}.{}".format(args[0].__class_.__name__, func.__name__) # pylint: disable=protected-access + return func.__name__ def set_span_contexts(wrapped_span, span_instance=None): - # type: (AbstractSpan, Optional[AbstractSpan]) -> None + # type: (Union[AbstractSpan, None], Optional[AbstractSpan]) -> None """ Set the sdk context and the implementation context. `span_instance` will be used to set the implementation context if passed in else will use `wrapped_span.span_instance`. diff --git a/sdk/core/azure-core/azure/core/tracing/context.py b/sdk/core/azure-core/azure/core/tracing/context.py index f8761cd71502..e27b8e4ce82e 100644 --- a/sdk/core/azure-core/azure/core/tracing/context.py +++ b/sdk/core/azure-core/azure/core/tracing/context.py @@ -29,8 +29,8 @@ class ContextProtocol(Protocol): Implements set and get variables in a thread safe way. """ - def __init__(self, name, default): - # type: (string, Any) -> None + def __init__(self, name, default): # pylint: disable=super-init-not-called + # type: (str, Any) -> None pass def clear(self): @@ -55,8 +55,9 @@ class _AsyncContext(object): """ def __init__(self, name, default): + # type: (str, Any) -> None self.name = name - self.contextvar = contextvars.ContextVar(name) + self.contextvar = contextvars.ContextVar(name) # type: contextvars.ContextVar self.default = default if callable(default) else (lambda: default) def clear(self): @@ -84,6 +85,7 @@ class _ThreadLocalContext(object): """ Uses thread local storage to set and get variables globally in a thread safe way. """ + _thread_local = threading.local() def __init__(self, name, default): @@ -115,7 +117,7 @@ def set(self, value): class TracingContext(object): def __init__(self): # type: () -> None - context_class = _AsyncContext if contextvars else _ThreadLocalContext + context_class = _AsyncContext if contextvars else _ThreadLocalContext # type: ContextProtocol self.current_span = context_class("current_span", None) def with_current_context(self, func): @@ -141,4 +143,5 @@ def call_with_current_context(*args, **kwargs): return call_with_current_context + tracing_context = TracingContext() diff --git a/sdk/core/azure-core/azure/core/tracing/decorator.py b/sdk/core/azure-core/azure/core/tracing/decorator.py index 3986dcaf31ed..136fafed09ec 100644 --- a/sdk/core/azure-core/azure/core/tracing/decorator.py +++ b/sdk/core/azure-core/azure/core/tracing/decorator.py @@ -31,15 +31,23 @@ from azure.core.settings import settings from azure.core.tracing.context import tracing_context +try: + from typing import TYPE_CHECKING +except ImportError: + TYPE_CHECKING = False + +if TYPE_CHECKING: + from typing import Callable, Any + def distributed_trace(func=None, name_of_span=None): - # type: (Callable[[Any], Any], str) -> Callable[[Any], Any] + # type: (Callable, str) -> Callable[[Any], Any] if func is None: return functools.partial(distributed_trace, name_of_span=name_of_span) @functools.wraps(func) - def wrapper_use_tracer(self, *args, **kwargs): - # type: (Any) -> Any + def wrapper_use_tracer(*args, **kwargs): + # type: (Any, Any) -> Any passed_in_parent = kwargs.pop("parent_span", None) orig_wrapped_span = tracing_context.current_span.get() wrapper_class = settings.tracing_implementation() @@ -50,18 +58,20 @@ def wrapper_use_tracer(self, *args, **kwargs): ans = None if parent_span is not None and orig_wrapped_span is None: common.set_span_contexts(parent_span) - name = name_of_span or self.__class__.__name__ + "." + func.__name__ + name = ( + name_of_span or getattr(func, "__qualname__", None) or common.get_function_and_class_name(func, *args) + ) child = parent_span.span(name=name) child.start() common.set_span_contexts(child) - ans = func(self, *args, **kwargs) + ans = func(*args, **kwargs) child.finish() common.set_span_contexts(parent_span) if orig_wrapped_span is None and passed_in_parent is None and original_span_instance is None: parent_span.finish() common.set_span_contexts(orig_wrapped_span, span_instance=original_span_instance) else: - ans = func(self, *args, **kwargs) + ans = func(*args, **kwargs) return ans return wrapper_use_tracer diff --git a/sdk/core/azure-core/azure/core/tracing/decorator_async.py b/sdk/core/azure-core/azure/core/tracing/decorator_async.py index 4df65fee77ef..2855d91a56ff 100644 --- a/sdk/core/azure-core/azure/core/tracing/decorator_async.py +++ b/sdk/core/azure-core/azure/core/tracing/decorator_async.py @@ -31,15 +31,23 @@ from azure.core.settings import settings from azure.core.tracing.context import tracing_context +try: + from typing import TYPE_CHECKING +except ImportError: + TYPE_CHECKING = False + +if TYPE_CHECKING: + from typing import Callable, Any + def distributed_trace_async(func=None, name_of_span=None): - # type: (Callable[[Any], Any], str) -> Callable[[Any], Any] + # type: (Callable, str) -> Callable[[Any], Any] if func is None: return functools.partial(distributed_trace_async, name_of_span=name_of_span) @functools.wraps(func) - async def wrapper_use_tracer(self, *args, **kwargs): - # type: (Any) -> Any + async def wrapper_use_tracer(*args, **kwargs): + # type: (Any, Any) -> Any passed_in_parent = kwargs.pop("parent_span", None) orig_wrapped_span = tracing_context.current_span.get() wrapper_class = settings.tracing_implementation() @@ -50,18 +58,20 @@ async def wrapper_use_tracer(self, *args, **kwargs): ans = None if parent_span is not None and orig_wrapped_span is None: common.set_span_contexts(parent_span) - name = name_of_span or self.__class__.__name__ + "." + func.__name__ + name = ( + name_of_span or getattr(func, "__qualname__", None) or common.get_function_and_class_name(func, *args) + ) child = parent_span.span(name=name) child.start() common.set_span_contexts(child) - ans = await func(self, *args, **kwargs) + ans = await func(*args, **kwargs) child.finish() common.set_span_contexts(parent_span) if orig_wrapped_span is None and passed_in_parent is None and original_span_instance is None: parent_span.finish() common.set_span_contexts(orig_wrapped_span, span_instance=original_span_instance) else: - ans = await func(self, *args, **kwargs) + ans = await func(*args, **kwargs) return ans return wrapper_use_tracer diff --git a/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py b/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py index 7aeb79c77e36..ff21dab515f8 100644 --- a/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py +++ b/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py @@ -80,7 +80,7 @@ def to_header(self): :return: A key value pair dictionary """ tracer_from_context = self.get_current_tracer() - temp_headers = {} + temp_headers = {} # type: Dict[str, str] if tracer_from_context is not None: ctx = tracer_from_context.span_context try: From 6d50311e45a28cd35573cde409615d670d1aaea4 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Wed, 31 Jul 2019 16:59:34 -0700 Subject: [PATCH 5/9] added test for get_name and moved stuff in the function --- sdk/core/azure-core/azure/core/tracing/common.py | 9 ++++++--- sdk/core/azure-core/azure/core/tracing/decorator.py | 4 +--- .../azure-core/azure/core/tracing/decorator_async.py | 4 +--- sdk/core/azure-core/tests/test_tracing_decorator.py | 10 ++++++++++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/sdk/core/azure-core/azure/core/tracing/common.py b/sdk/core/azure-core/azure/core/tracing/common.py index 8b024cf1d105..38490a3ef3d9 100644 --- a/sdk/core/azure-core/azure/core/tracing/common.py +++ b/sdk/core/azure-core/azure/core/tracing/common.py @@ -50,9 +50,12 @@ def get_function_and_class_name(func, *args): :param args: List of arguments passed into the function :type args: List[Any] """ - if args: - return "{}.{}".format(args[0].__class_.__name__, func.__name__) # pylint: disable=protected-access - return func.__name__ + try: + return func.__qualname__ + except AttributeError: + if args: + return "{}.{}".format(args[0].__class_.__name__, func.__name__) # pylint: disable=protected-access + return func.__name__ def set_span_contexts(wrapped_span, span_instance=None): diff --git a/sdk/core/azure-core/azure/core/tracing/decorator.py b/sdk/core/azure-core/azure/core/tracing/decorator.py index 136fafed09ec..7b6ebb26cf45 100644 --- a/sdk/core/azure-core/azure/core/tracing/decorator.py +++ b/sdk/core/azure-core/azure/core/tracing/decorator.py @@ -58,9 +58,7 @@ def wrapper_use_tracer(*args, **kwargs): ans = None if parent_span is not None and orig_wrapped_span is None: common.set_span_contexts(parent_span) - name = ( - name_of_span or getattr(func, "__qualname__", None) or common.get_function_and_class_name(func, *args) - ) + name = name_of_span or common.get_function_and_class_name(func, *args) child = parent_span.span(name=name) child.start() common.set_span_contexts(child) diff --git a/sdk/core/azure-core/azure/core/tracing/decorator_async.py b/sdk/core/azure-core/azure/core/tracing/decorator_async.py index 2855d91a56ff..0719a9c016c3 100644 --- a/sdk/core/azure-core/azure/core/tracing/decorator_async.py +++ b/sdk/core/azure-core/azure/core/tracing/decorator_async.py @@ -58,9 +58,7 @@ async def wrapper_use_tracer(*args, **kwargs): ans = None if parent_span is not None and orig_wrapped_span is None: common.set_span_contexts(parent_span) - name = ( - name_of_span or getattr(func, "__qualname__", None) or common.get_function_and_class_name(func, *args) - ) + name = name_of_span or common.get_function_and_class_name(func, *args) child = parent_span.span(name=name) child.start() common.set_span_contexts(child) diff --git a/sdk/core/azure-core/tests/test_tracing_decorator.py b/sdk/core/azure-core/tests/test_tracing_decorator.py index 764c09396255..c51b87a95772 100644 --- a/sdk/core/azure-core/tests/test_tracing_decorator.py +++ b/sdk/core/azure-core/tests/test_tracing_decorator.py @@ -68,7 +68,17 @@ def check_name_is_different(self): time.sleep(0.001) +def random_function(): + pass + + class TestCommon(object): + def test_get_function_and_class_name(self): + with ContextHelper(): + client = MockClient() + assert common.get_function_and_class_name(client.get_foo) == "MockClient.get_foo" + assert common.get_function_and_class_name(random_function) == "random_function" + def test_set_span_context(self): with ContextHelper(environ={"AZURE_SDK_TRACING_IMPLEMENTATION": "opencensus"}): wrapper = settings.tracing_implementation() From 15a1cef53cf842be59b096f065c94298d6319445 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Thu, 1 Aug 2019 09:44:42 -0700 Subject: [PATCH 6/9] small ci fix --- sdk/core/azure-core/azure/core/tracing/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/azure-core/azure/core/tracing/common.py b/sdk/core/azure-core/azure/core/tracing/common.py index 38490a3ef3d9..f245e600276f 100644 --- a/sdk/core/azure-core/azure/core/tracing/common.py +++ b/sdk/core/azure-core/azure/core/tracing/common.py @@ -54,7 +54,7 @@ def get_function_and_class_name(func, *args): return func.__qualname__ except AttributeError: if args: - return "{}.{}".format(args[0].__class_.__name__, func.__name__) # pylint: disable=protected-access + return "{}.{}".format(args[0].__class__.__name__, func.__name__) # pylint: disable=protected-access return func.__name__ From 87e72261174284ccfdb19774c335a9a7ab5f8b24 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Thu, 1 Aug 2019 17:07:56 -0700 Subject: [PATCH 7/9] more mypy fixes --- .../azure-core/azure/core/tracing/abstract_span.py | 2 +- sdk/core/azure-core/azure/core/tracing/common.py | 4 ++-- sdk/core/azure-core/azure/core/tracing/context.py | 10 ++++++---- .../azure/core/tracing/ext/opencensus_span.py | 11 +++++------ sdk/core/azure-core/tests/test_tracing_decorator.py | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/sdk/core/azure-core/azure/core/tracing/abstract_span.py b/sdk/core/azure-core/azure/core/tracing/abstract_span.py index 9b7ca6753c0a..e5597d48df5e 100644 --- a/sdk/core/azure-core/azure/core/tracing/abstract_span.py +++ b/sdk/core/azure-core/azure/core/tracing/abstract_span.py @@ -17,7 +17,7 @@ try: from typing_extensions import Protocol except ImportError: - Protocol = object + Protocol = object # type: ignore class AbstractSpan(Protocol): diff --git a/sdk/core/azure-core/azure/core/tracing/common.py b/sdk/core/azure-core/azure/core/tracing/common.py index f245e600276f..22cea6315e73 100644 --- a/sdk/core/azure-core/azure/core/tracing/common.py +++ b/sdk/core/azure-core/azure/core/tracing/common.py @@ -36,7 +36,7 @@ TYPE_CHECKING = False if TYPE_CHECKING: - from typing import Any, Optional, Union, Callable + from typing import Any, Optional, Union, Callable, List def get_function_and_class_name(func, *args): @@ -77,7 +77,7 @@ def set_span_contexts(wrapped_span, span_instance=None): def get_parent_span(parent_span): - # type: (Any) -> Tuple(AbstractSpan, AbstractSpan, Any) + # type: (Any) -> Optional[AbstractSpan] """ Returns the current span so that the function's span will be its child. It will create a new span if there is no current span in any of the context. diff --git a/sdk/core/azure-core/azure/core/tracing/context.py b/sdk/core/azure-core/azure/core/tracing/context.py index e27b8e4ce82e..ecf822bf6fd7 100644 --- a/sdk/core/azure-core/azure/core/tracing/context.py +++ b/sdk/core/azure-core/azure/core/tracing/context.py @@ -13,7 +13,7 @@ TYPE_CHECKING = False if TYPE_CHECKING: - from typing import Any, Callable + from typing import Any, Callable, Optional, Type, Union from typing_extensions import Protocol else: Protocol = object @@ -21,7 +21,7 @@ try: import contextvars except ImportError: - contextvars = None + pass class ContextProtocol(Protocol): @@ -117,8 +117,10 @@ def set(self, value): class TracingContext(object): def __init__(self): # type: () -> None - context_class = _AsyncContext if contextvars else _ThreadLocalContext # type: ContextProtocol - self.current_span = context_class("current_span", None) + try: + self.current_span = _AsyncContext("current_span", None) # type: Union[_AsyncContext, _ThreadLocalContext] + except NameError: + self.current_span = _ThreadLocalContext("current_span", None) def with_current_context(self, func): # type: (Callable[[Any], Any]) -> Any diff --git a/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py b/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py index ff21dab515f8..c1fd6eb6a4e0 100644 --- a/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py +++ b/sdk/core/azure-core/azure/core/tracing/ext/opencensus_span.py @@ -5,6 +5,7 @@ """Implements azure.core.tracing.AbstractSpan to wrap opencensus spans.""" from opencensus.trace import Span, execution_context +from opencensus.trace.tracer import Tracer from opencensus.trace.span import SpanKind from opencensus.trace.link import Link from opencensus.trace.propagation import trace_context_http_header_format @@ -34,10 +35,8 @@ def __init__(self, span=None, name="span"): :param name: The name of the OpenCensus span to create if a new span is needed :type name: str """ - if not span: - tracer = self.get_current_tracer() - span = tracer.start_span(name=name) # type: Span - self._span_instance = span + tracer = self.get_current_tracer() + self._span_instance = span or tracer.start_span(name=name) self._span_component = "component" self._http_user_agent = "http.user_agent" self._http_method = "http.method" @@ -146,7 +145,7 @@ def get_current_span(cls): @classmethod def get_current_tracer(cls): - # type: () -> tracer_module.Tracer + # type: () -> Tracer """ Get the current tracer from the execution context. Return None otherwise. """ @@ -165,7 +164,7 @@ def set_current_span(cls, span): @classmethod def set_current_tracer(cls, tracer): - # type: (tracer_module.Tracer) -> None + # type: (Tracer) -> None """ Set the given tracer as the current tracer in the execution context. :param tracer: The tracer to set the current tracer as diff --git a/sdk/core/azure-core/tests/test_tracing_decorator.py b/sdk/core/azure-core/tests/test_tracing_decorator.py index c51b87a95772..5c5a1df7b9e6 100644 --- a/sdk/core/azure-core/tests/test_tracing_decorator.py +++ b/sdk/core/azure-core/tests/test_tracing_decorator.py @@ -76,7 +76,7 @@ class TestCommon(object): def test_get_function_and_class_name(self): with ContextHelper(): client = MockClient() - assert common.get_function_and_class_name(client.get_foo) == "MockClient.get_foo" + assert common.get_function_and_class_name(client.get_foo, client) == "MockClient.get_foo" assert common.get_function_and_class_name(random_function) == "random_function" def test_set_span_context(self): From 471b1c7f40e354802e6053baadaedb22d9126dcb Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Thu, 1 Aug 2019 17:10:46 -0700 Subject: [PATCH 8/9] get rid of dependency --- sdk/core/azure-core/setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/core/azure-core/setup.py b/sdk/core/azure-core/setup.py index e5bbaebb52c5..bdab06be195c 100644 --- a/sdk/core/azure-core/setup.py +++ b/sdk/core/azure-core/setup.py @@ -65,6 +65,5 @@ ], extras_require={ ":python_version<'3.0'": ['azure-nspkg'], - ":python_version>='3.5'": ['contextvars'], } ) From 78ef0ad6579aa27361eb31195b863178b5b2b961 Mon Sep 17 00:00:00 2001 From: Suyog Soti Date: Thu, 1 Aug 2019 17:19:55 -0700 Subject: [PATCH 9/9] all use same context --- .../azure-core/tests/test_tracing_context.py | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/sdk/core/azure-core/tests/test_tracing_context.py b/sdk/core/azure-core/tests/test_tracing_context.py index 984d2ad480d3..875c98105348 100644 --- a/sdk/core/azure-core/tests/test_tracing_context.py +++ b/sdk/core/azure-core/tests/test_tracing_context.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. # ------------------------------------ import unittest + try: from unittest import mock except ImportError: @@ -11,28 +12,10 @@ from azure.core.tracing.context import tracing_context from azure.core.tracing import AbstractSpan from azure.core.settings import settings +from tracing_common import ContextHelper import os -class ContextHelper(object): - def __init__(self, environ={}, tracer_to_use=None): - self.orig_sdk_context_span = tracing_context.current_span.get() - self.os_env = mock.patch.dict(os.environ, environ) - self.tracer_to_use = tracer_to_use - - def __enter__(self): - self.orig_sdk_context_span = tracing_context.current_span.get() - tracing_context.current_span.clear() - settings.tracing_implementation.set_value(self.tracer_to_use) - self.os_env.start() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - tracing_context.current_span.set(self.orig_sdk_context_span) - settings.tracing_implementation.unset_value() - self.os_env.stop() - - class TestContext(unittest.TestCase): def test_current_span(self): with ContextHelper():