diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md b/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md deleted file mode 100644 index be243d958..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# Changelog - -## Unreleased - -## Version 0.13b0 - -Released 2020-09-17 - -- Drop support for Python 3.4 - ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) - -## Version 0.12b0 - -Released 2020-08-14 - -- Change reference names to opentelemetry-instrumentation-opentracing-shim - ([#969](https://github.com/open-telemetry/opentelemetry-python/pull/969)) - -## 0.3a0 - -Released 2019-12-11 - -- Implement extract and inject support for HTTP_HEADERS and TEXT_MAP formats - ([#256](https://github.com/open-telemetry/opentelemetry-python/pull/256)) - -## 0.2a0 - -Released 2019-10-29 - -- Initial release diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/LICENSE b/instrumentation/opentelemetry-instrumentation-opentracing-shim/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/MANIFEST.in b/instrumentation/opentelemetry-instrumentation-opentracing-shim/MANIFEST.in deleted file mode 100644 index aed3e3327..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -graft src -graft tests -global-exclude *.pyc -global-exclude *.pyo -global-exclude __pycache__/* -include CHANGELOG.md -include MANIFEST.in -include README.rst -include LICENSE diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/README.rst deleted file mode 100644 index 7a8413ef5..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/README.rst +++ /dev/null @@ -1,20 +0,0 @@ -OpenTracing Shim for OpenTelemetry -================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-opentracing-shim.svg - :target: https://pypi.org/project/opentelemetry-opentracing-shim/ - -Installation ------------- - -:: - - pip install opentelemetry-opentracing-shim - -References ----------- - -* `OpenTracing Shim for OpenTelemetry `_ -* `OpenTelemetry Project `_ diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg deleted file mode 100644 index 8247d1d51..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -[metadata] -name = opentelemetry-opentracing-shim -description = OpenTracing Shim for OpenTelemetry -long_description = file: README.rst -long_description_content_type = text/x-rst -author = OpenTelemetry Authors -author_email = cncf-opentelemetry-contributors@lists.cncf.io -url = https://github.com/open-telemetry/opentelemetry-python/tree/master/instrumentation/opentelemetry-instrumentation-opentracing-shim -platforms = any -license = Apache-2.0 -classifiers = - Development Status :: 4 - Beta - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - -[options] -python_requires = >=3.5 -package_dir= - =src -packages=find_namespace: -install_requires = - Deprecated >= 1.2.6 - opentracing ~= 2.0 - opentelemetry-api == 0.15.dev0 - -[options.extras_require] -test = - opentelemetry-test == 0.15.dev0 - opentracing ~= 2.2.0 - -[options.packages.find] -where = src diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.py deleted file mode 100644 index f5d71a86b..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import os - -import setuptools - -BASE_DIR = os.path.dirname(__file__) -VERSION_FILENAME = os.path.join( - BASE_DIR, - "src", - "opentelemetry", - "instrumentation", - "opentracing_shim", - "version.py", -) -PACKAGE_INFO = {} -with open(VERSION_FILENAME) as f: - exec(f.read(), PACKAGE_INFO) - -setuptools.setup(version=PACKAGE_INFO["__version__"]) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/__init__.py deleted file mode 100644 index 63be13fe4..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/__init__.py +++ /dev/null @@ -1,725 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -The OpenTelemetry OpenTracing shim is a library which allows an easy migration -from OpenTracing to OpenTelemetry. - -The shim consists of a set of classes which implement the OpenTracing Python -API while using OpenTelemetry constructs behind the scenes. Its purpose is to -allow applications which are already instrumented using OpenTracing to start -using OpenTelemetry with a minimal effort, without having to rewrite large -portions of the codebase. - -To use the shim, a :class:`TracerShim` instance is created and then used as if -it were an "ordinary" OpenTracing :class:`opentracing.Tracer`, as in the -following example:: - - import time - - from opentelemetry import trace - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.instrumentation.opentracing_shim import create_tracer - - # Define which OpenTelemetry Tracer provider implementation to use. - trace.set_tracer_provider(TracerProvider()) - - # Create an OpenTelemetry Tracer. - otel_tracer = trace.get_tracer(__name__) - - # Create an OpenTracing shim. - shim = create_tracer(otel_tracer) - - with shim.start_active_span("ProcessHTTPRequest"): - print("Processing HTTP request") - # Sleeping to mock real work. - time.sleep(0.1) - with shim.start_active_span("GetDataFromDB"): - print("Getting data from DB") - # Sleeping to mock real work. - time.sleep(0.2) - -Note: - While the OpenTracing Python API represents time values as the number of - **seconds** since the epoch expressed as :obj:`float` values, the - OpenTelemetry Python API represents time values as the number of - **nanoseconds** since the epoch expressed as :obj:`int` values. This fact - requires the OpenTracing shim to convert time values back and forth between - the two representations, which involves floating point arithmetic. - - Due to the way computers represent floating point values in hardware, - representation of decimal floating point values in binary-based hardware is - imprecise by definition. - - The above results in **slight imprecisions** in time values passed to the - shim via the OpenTracing API when comparing the value passed to the shim - and the value stored in the OpenTelemetry :class:`opentelemetry.trace.Span` - object behind the scenes. **This is not a bug in this library or in - Python**. Rather, this is a generic problem which stems from the fact that - not every decimal floating point number can be correctly represented in - binary, and therefore affects other libraries and programming languages as - well. More information about this problem can be found in the - `Floating Point Arithmetic\\: Issues and Limitations`_ section of the - Python documentation. - - While testing this library, the aforementioned imprecisions were observed - to be of *less than a microsecond*. - -API ---- -.. _Floating Point Arithmetic\\: Issues and Limitations: - https://docs.python.org/3/tutorial/floatingpoint.html -""" - -# TODO: make pylint use 3p opentracing module for type inference -# pylint:disable=no-member - -import logging -from typing import Optional, TypeVar, Union - -from deprecated import deprecated -from opentracing import ( - Format, - Scope, - ScopeManager, - Span, - SpanContext, - Tracer, - UnsupportedFormatException, -) - -from opentelemetry import propagators -from opentelemetry.baggage import get_baggage, set_baggage -from opentelemetry.context import Context, attach, detach, get_value, set_value -from opentelemetry.instrumentation.opentracing_shim import util -from opentelemetry.instrumentation.opentracing_shim.version import __version__ -from opentelemetry.trace import INVALID_SPAN_CONTEXT, DefaultSpan, Link -from opentelemetry.trace import SpanContext as OtelSpanContext -from opentelemetry.trace import Tracer as OtelTracer -from opentelemetry.trace import ( - TracerProvider, - get_current_span, - set_span_in_context, -) -from opentelemetry.util.types import Attributes - -ValueT = TypeVar("ValueT", int, float, bool, str) -logger = logging.getLogger(__name__) - - -def create_tracer(otel_tracer_provider: TracerProvider) -> "TracerShim": - """Creates a :class:`TracerShim` object from the provided OpenTelemetry - :class:`opentelemetry.trace.TracerProvider`. - - The returned :class:`TracerShim` is an implementation of - :class:`opentracing.Tracer` using OpenTelemetry under the hood. - - Args: - otel_tracer_provider: A tracer from this provider will be used to - perform the actual tracing when user code is instrumented using the - OpenTracing API. - - Returns: - The created :class:`TracerShim`. - """ - - return TracerShim(otel_tracer_provider.get_tracer(__name__, __version__)) - - -class SpanContextShim(SpanContext): - """Implements :class:`opentracing.SpanContext` by wrapping a - :class:`opentelemetry.trace.SpanContext` object. - - Args: - otel_context: A :class:`opentelemetry.trace.SpanContext` to be used for - constructing the :class:`SpanContextShim`. - """ - - def __init__(self, otel_context: OtelSpanContext): - self._otel_context = otel_context - # Context is being used here since it must be immutable. - self._baggage = Context() - - def unwrap(self) -> OtelSpanContext: - """Returns the wrapped :class:`opentelemetry.trace.SpanContext` - object. - - Returns: - The :class:`opentelemetry.trace.SpanContext` object wrapped by this - :class:`SpanContextShim`. - """ - - return self._otel_context - - @property - def baggage(self) -> Context: - """Returns the ``baggage`` associated with this object""" - - return self._baggage - - -class SpanShim(Span): - """Wraps a :class:`opentelemetry.trace.Span` object. - - Args: - tracer: The :class:`opentracing.Tracer` that created this `SpanShim`. - context: A :class:`SpanContextShim` which contains the context for this - :class:`SpanShim`. - span: A :class:`opentelemetry.trace.Span` to wrap. - """ - - def __init__(self, tracer, context: SpanContextShim, span): - super().__init__(tracer, context) - self._otel_span = span - - def unwrap(self): - """Returns the wrapped :class:`opentelemetry.trace.Span` object. - - Returns: - The :class:`opentelemetry.trace.Span` object wrapped by this - :class:`SpanShim`. - """ - - return self._otel_span - - def set_operation_name(self, operation_name: str) -> "SpanShim": - """Updates the name of the wrapped OpenTelemetry span. - - Args: - operation_name: The new name to be used for the underlying - :class:`opentelemetry.trace.Span` object. - - Returns: - Returns this :class:`SpanShim` instance to allow call chaining. - """ - - self._otel_span.update_name(operation_name) - return self - - def finish(self, finish_time: float = None): - """Ends the OpenTelemetry span wrapped by this :class:`SpanShim`. - - If *finish_time* is provided, the time value is converted to the - OpenTelemetry time format (number of nanoseconds since the epoch, - expressed as an integer) and passed on to the OpenTelemetry tracer when - ending the OpenTelemetry span. If *finish_time* isn't provided, it is - up to the OpenTelemetry tracer implementation to generate a timestamp - when ending the span. - - Args: - finish_time: A value that represents the finish time expressed as - the number of seconds since the epoch as returned by - :func:`time.time()`. - """ - - end_time = finish_time - if end_time is not None: - end_time = util.time_seconds_to_ns(finish_time) - self._otel_span.end(end_time=end_time) - - def set_tag(self, key: str, value: ValueT) -> "SpanShim": - """Sets an OpenTelemetry attribute on the wrapped OpenTelemetry span. - - Args: - key: A tag key. - value: A tag value. - - Returns: - Returns this :class:`SpanShim` instance to allow call chaining. - """ - - self._otel_span.set_attribute(key, value) - return self - - def log_kv( - self, key_values: Attributes, timestamp: float = None - ) -> "SpanShim": - """Logs an event for the wrapped OpenTelemetry span. - - Note: - The OpenTracing API defines the values of *key_values* to be of any - type. However, the OpenTelemetry API requires that the values be - any one of the types defined in - ``opentelemetry.trace.util.Attributes`` therefore, only these types - are supported as values. - - Args: - key_values: A dictionary as specified in - ``opentelemetry.trace.util.Attributes``. - timestamp: Timestamp of the OpenTelemetry event, will be generated - automatically if omitted. - - Returns: - Returns this :class:`SpanShim` instance to allow call chaining. - """ - - if timestamp is not None: - event_timestamp = util.time_seconds_to_ns(timestamp) - else: - event_timestamp = None - - event_name = util.event_name_from_kv(key_values) - self._otel_span.add_event(event_name, key_values, event_timestamp) - return self - - @deprecated(reason="This method is deprecated in favor of log_kv") - def log(self, **kwargs): - super().log(**kwargs) - - @deprecated(reason="This method is deprecated in favor of log_kv") - def log_event(self, event, payload=None): - super().log_event(event, payload=payload) - - def set_baggage_item(self, key: str, value: str): - """Stores a Baggage item in the span as a key/value - pair. - - Args: - key: A tag key. - value: A tag value. - """ - # pylint: disable=protected-access - self._context._baggage = set_baggage( - key, value, context=self._context._baggage - ) - - def get_baggage_item(self, key: str) -> Optional[object]: - """Retrieves value of the baggage item with the given key. - - Args: - key: A tag key. - Returns: - Returns this :class:`SpanShim` instance to allow call chaining. - """ - # pylint: disable=protected-access - return get_baggage(key, context=self._context._baggage) - - -class ScopeShim(Scope): - """A `ScopeShim` wraps the OpenTelemetry functionality related to span - activation/deactivation while using OpenTracing :class:`opentracing.Scope` - objects for presentation. - - Unlike other classes in this package, the `ScopeShim` class doesn't wrap an - OpenTelemetry class because OpenTelemetry doesn't have the notion of - "scope" (though it *does* have similar functionality). - - There are two ways to construct a `ScopeShim` object: using the default - initializer and using the :meth:`from_context_manager()` class method. - - It is necessary to have both ways for constructing `ScopeShim` objects - because in some cases we need to create the object from an OpenTelemetry - `opentelemetry.trace.Span` context manager (as returned by - :meth:`opentelemetry.trace.Tracer.use_span`), in which case our only way of - retrieving a `opentelemetry.trace.Span` object is by calling the - ``__enter__()`` method on the context manager, which makes the span active - in the OpenTelemetry tracer; whereas in other cases we need to accept a - `SpanShim` object and wrap it in a `ScopeShim`. The former is used mainly - when the instrumentation code retrieves the currently-active span using - `ScopeManagerShim.active`. The latter is mainly used when the - instrumentation code activates a span using - :meth:`ScopeManagerShim.activate`. - - Args: - manager: The :class:`ScopeManagerShim` that created this - :class:`ScopeShim`. - span: The :class:`SpanShim` this :class:`ScopeShim` controls. - span_cm: A Python context manager which yields an OpenTelemetry - `opentelemetry.trace.Span` from its ``__enter__()`` method. Used - by :meth:`from_context_manager` to store the context manager as - an attribute so that it can later be closed by calling its - ``__exit__()`` method. Defaults to `None`. - """ - - def __init__( - self, manager: "ScopeManagerShim", span: SpanShim, span_cm=None - ): - super().__init__(manager, span) - self._span_cm = span_cm - self._token = attach(set_value("scope_shim", self)) - - # TODO: Change type of `manager` argument to `opentracing.ScopeManager`? We - # need to get rid of `manager.tracer` for this. - @classmethod - def from_context_manager(cls, manager: "ScopeManagerShim", span_cm): - """Constructs a :class:`ScopeShim` from an OpenTelemetry - `opentelemetry.trace.Span` context - manager. - - The method extracts a `opentelemetry.trace.Span` object from the - context manager by calling the context manager's ``__enter__()`` - method. This causes the span to start in the OpenTelemetry tracer. - - Example usage:: - - span = otel_tracer.start_span("TestSpan") - span_cm = otel_tracer.use_span(span) - scope_shim = ScopeShim.from_context_manager( - scope_manager_shim, - span_cm=span_cm, - ) - - Args: - manager: The :class:`ScopeManagerShim` that created this - :class:`ScopeShim`. - span_cm: A context manager as returned by - :meth:`opentelemetry.trace.Tracer.use_span`. - """ - - otel_span = span_cm.__enter__() - span_context = SpanContextShim(otel_span.get_span_context()) - span = SpanShim(manager.tracer, span_context, otel_span) - return cls(manager, span, span_cm) - - def close(self): - """Closes the `ScopeShim`. If the `ScopeShim` was created from a - context manager, calling this method sets the active span in the - OpenTelemetry tracer back to the span which was active before this - `ScopeShim` was created. In addition, if the span represented by this - `ScopeShim` was activated with the *finish_on_close* argument set to - `True`, calling this method will end the span. - - Warning: - In the current state of the implementation it is possible to create - a `ScopeShim` directly from a `SpanShim`, that is - without using - :meth:`from_context_manager()`. For that reason we need to be able - to end the span represented by the `ScopeShim` in this case, too. - Please note that closing a `ScopeShim` created this way (for - example as returned by :meth:`ScopeManagerShim.active`) **always - ends the associated span**, regardless of the value passed in - *finish_on_close* when activating the span. - """ - - detach(self._token) - - if self._span_cm is not None: - # We don't have error information to pass to `__exit__()` so we - # pass `None` in all arguments. If the OpenTelemetry tracer - # implementation requires this information, the `__exit__()` method - # on `opentracing.Scope` should be overridden and modified to pass - # the relevant values to this `close()` method. - self._span_cm.__exit__(None, None, None) - else: - self._span.unwrap().end() - - -class ScopeManagerShim(ScopeManager): - """Implements :class:`opentracing.ScopeManager` by setting and getting the - active `opentelemetry.trace.Span` in the OpenTelemetry tracer. - - This class keeps a reference to a :class:`TracerShim` as an attribute. This - reference is used to communicate with the OpenTelemetry tracer. It is - necessary to have a reference to the :class:`TracerShim` rather than the - :class:`opentelemetry.trace.Tracer` wrapped by it because when constructing - a :class:`SpanShim` we need to pass a reference to a - :class:`opentracing.Tracer`. - - Args: - tracer: A :class:`TracerShim` to use for setting and getting active - span state. - """ - - def __init__(self, tracer: "TracerShim"): - # The only thing the ``__init__()``` method on the base class does is - # initialize `self._noop_span` and `self._noop_scope` with no-op - # objects. Therefore, it doesn't seem useful to call it. - # pylint: disable=super-init-not-called - self._tracer = tracer - - def activate(self, span: SpanShim, finish_on_close: bool) -> "ScopeShim": - """Activates a :class:`SpanShim` and returns a :class:`ScopeShim` which - represents the active span. - - Args: - span: A :class:`SpanShim` to be activated. - finish_on_close(:obj:`bool`): Determines whether the OpenTelemetry - span should be ended when the returned :class:`ScopeShim` is - closed. - - Returns: - A :class:`ScopeShim` representing the activated span. - """ - - span_cm = self._tracer.unwrap().use_span( - span.unwrap(), end_on_exit=finish_on_close - ) - return ScopeShim.from_context_manager(self, span_cm=span_cm) - - @property - def active(self) -> "ScopeShim": - """Returns a :class:`ScopeShim` object representing the - currently-active span in the OpenTelemetry tracer. - - Returns: - A :class:`ScopeShim` representing the active span in the - OpenTelemetry tracer, or `None` if no span is currently active. - - Warning: - Calling :meth:`ScopeShim.close` on the :class:`ScopeShim` returned - by this property **always ends the corresponding span**, regardless - of the *finish_on_close* value used when activating the span. This - is a limitation of the current implementation of the OpenTracing - shim and is likely to be handled in future versions. - """ - - span = get_current_span() - if span.get_span_context() == INVALID_SPAN_CONTEXT: - return None - - try: - return get_value("scope_shim") - except KeyError: - span_context = SpanContextShim(span.get_span_context()) - wrapped_span = SpanShim(self._tracer, span_context, span) - return ScopeShim(self, span=wrapped_span) - - @property - def tracer(self) -> "TracerShim": - """Returns the :class:`TracerShim` reference used by this - :class:`ScopeManagerShim` for setting and getting the active span from - the OpenTelemetry tracer. - - Returns: - The :class:`TracerShim` used for setting and getting the active - span. - - Warning: - This property is *not* a part of the OpenTracing API. It used - internally by the current implementation of the OpenTracing shim - and will likely be removed in future versions. - """ - - return self._tracer - - -class TracerShim(Tracer): - """Wraps a :class:`opentelemetry.trace.Tracer` object. - - This wrapper class allows using an OpenTelemetry tracer as if it were an - OpenTracing tracer. It exposes the same methods as an "ordinary" - OpenTracing tracer, and uses OpenTelemetry transparently for performing the - actual tracing. - - This class depends on the *OpenTelemetry API*. Therefore, any - implementation of a :class:`opentelemetry.trace.Tracer` should work with - this class. - - Args: - tracer: A :class:`opentelemetry.trace.Tracer` to use for tracing. This - tracer will be invoked by the shim to create actual spans. - """ - - def __init__(self, tracer: OtelTracer): - super().__init__(scope_manager=ScopeManagerShim(self)) - self._otel_tracer = tracer - self._supported_formats = ( - Format.TEXT_MAP, - Format.HTTP_HEADERS, - ) - - def unwrap(self): - """Returns the :class:`opentelemetry.trace.Tracer` object that is - wrapped by this :class:`TracerShim` and used for actual tracing. - - Returns: - The :class:`opentelemetry.trace.Tracer` used for actual tracing. - """ - - return self._otel_tracer - - def start_active_span( - self, - operation_name: str, - child_of: Union[SpanShim, SpanContextShim] = None, - references: list = None, - tags: Attributes = None, - start_time: float = None, - ignore_active_span: bool = False, - finish_on_close: bool = True, - ) -> "ScopeShim": - """Starts and activates a span. In terms of functionality, this method - behaves exactly like the same method on a "regular" OpenTracing tracer. - See :meth:`opentracing.Tracer.start_active_span` for more details. - - Args: - operation_name: Name of the operation represented by - the new span from the perspective of the current service. - child_of: A :class:`SpanShim` or :class:`SpanContextShim` - representing the parent in a "child of" reference. If - specified, the *references* parameter must be omitted. - references: A list of :class:`opentracing.Reference` objects that - identify one or more parents of type :class:`SpanContextShim`. - tags: A dictionary of tags. - start_time: An explicit start time expressed as the number of - seconds since the epoch as returned by :func:`time.time()`. - ignore_active_span: Ignore the currently-active span in the - OpenTelemetry tracer and make the created span the root span of - a new trace. - finish_on_close: Determines whether the created span should end - automatically when closing the returned :class:`ScopeShim`. - - Returns: - A :class:`ScopeShim` that is already activated by the - :class:`ScopeManagerShim`. - """ - - current_span = get_current_span() - - if child_of is None and current_span is not INVALID_SPAN_CONTEXT: - child_of = SpanShim(None, None, current_span) - - span = self.start_span( - operation_name=operation_name, - child_of=child_of, - references=references, - tags=tags, - start_time=start_time, - ignore_active_span=ignore_active_span, - ) - return self._scope_manager.activate(span, finish_on_close) - - def start_span( - self, - operation_name: str = None, - child_of: Union[SpanShim, SpanContextShim] = None, - references: list = None, - tags: Attributes = None, - start_time: float = None, - ignore_active_span: bool = False, - ) -> SpanShim: - """Implements the ``start_span()`` method from the base class. - - Starts a span. In terms of functionality, this method behaves exactly - like the same method on a "regular" OpenTracing tracer. See - :meth:`opentracing.Tracer.start_span` for more details. - - Args: - operation_name: Name of the operation represented by the new span - from the perspective of the current service. - child_of: A :class:`SpanShim` or :class:`SpanContextShim` - representing the parent in a "child of" reference. If - specified, the *references* parameter must be omitted. - references: A list of :class:`opentracing.Reference` objects that - identify one or more parents of type :class:`SpanContextShim`. - tags: A dictionary of tags. - start_time: An explicit start time expressed as the number of - seconds since the epoch as returned by :func:`time.time()`. - ignore_active_span: Ignore the currently-active span in the - OpenTelemetry tracer and make the created span the root span of - a new trace. - - Returns: - An already-started :class:`SpanShim` instance. - """ - - # Use active span as parent when no explicit parent is specified. - if not ignore_active_span and not child_of: - child_of = self.active_span - - # Use the specified parent or the active span if possible. Otherwise, - # use a `None` parent, which triggers the creation of a new trace. - parent = child_of.unwrap() if child_of else None - if isinstance(parent, OtelSpanContext): - parent = DefaultSpan(parent) - - parent_span_context = set_span_in_context(parent) - - links = [] - if references: - for ref in references: - links.append(Link(ref.referenced_context.unwrap())) - - # The OpenTracing API expects time values to be `float` values which - # represent the number of seconds since the epoch. OpenTelemetry - # represents time values as nanoseconds since the epoch. - start_time_ns = start_time - if start_time_ns is not None: - start_time_ns = util.time_seconds_to_ns(start_time) - - span = self._otel_tracer.start_span( - operation_name, - context=parent_span_context, - links=links, - attributes=tags, - start_time=start_time_ns, - ) - - context = SpanContextShim(span.get_span_context()) - return SpanShim(self, context, span) - - def inject(self, span_context, format: object, carrier: object): - """Injects ``span_context`` into ``carrier``. - - See base class for more details. - - Args: - span_context: The ``opentracing.SpanContext`` to inject. - format: a Python object instance that represents a given - carrier format. `format` may be of any type, and `format` - equality is defined by Python ``==`` operator. - carrier: the format-specific carrier object to inject into - """ - - # pylint: disable=redefined-builtin - # This implementation does not perform the injecting by itself but - # uses the configured propagators in opentelemetry.propagators. - # TODO: Support Format.BINARY once it is supported in - # opentelemetry-python. - - if format not in self._supported_formats: - raise UnsupportedFormatException - - propagator = propagators.get_global_textmap() - - ctx = set_span_in_context(DefaultSpan(span_context.unwrap())) - propagator.inject(type(carrier).__setitem__, carrier, context=ctx) - - def extract(self, format: object, carrier: object): - """Returns an ``opentracing.SpanContext`` instance extracted from a - ``carrier``. - - See base class for more details. - - Args: - format: a Python object instance that represents a given - carrier format. ``format`` may be of any type, and ``format`` - equality is defined by python ``==`` operator. - carrier: the format-specific carrier object to extract from - - Returns: - An ``opentracing.SpanContext`` extracted from ``carrier`` or - ``None`` if no such ``SpanContext`` could be found. - """ - - # pylint: disable=redefined-builtin - # This implementation does not perform the extracing by itself but - # uses the configured propagators in opentelemetry.propagators. - # TODO: Support Format.BINARY once it is supported in - # opentelemetry-python. - if format not in self._supported_formats: - raise UnsupportedFormatException - - def get_as_list(dict_object, key): - value = dict_object.get(key) - return [value] if value is not None else [] - - propagator = propagators.get_global_textmap() - ctx = propagator.extract(get_as_list, carrier) - span = get_current_span(ctx) - if span is not None: - otel_context = span.get_span_context() - else: - otel_context = INVALID_SPAN_CONTEXT - - return SpanContextShim(otel_context) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/util.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/util.py deleted file mode 100644 index eb7d3d9ac..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/util.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# A default event name to be used for logging events when a better event name -# can't be derived from the event's key-value pairs. -DEFAULT_EVENT_NAME = "log" - - -def time_seconds_to_ns(time_seconds): - """Converts a time value in seconds to a time value in nanoseconds. - - `time_seconds` is a `float` as returned by `time.time()` which represents - the number of seconds since the epoch. - - The returned value is an `int` representing the number of nanoseconds since - the epoch. - """ - - return int(time_seconds * 1e9) - - -def time_seconds_from_ns(time_nanoseconds): - """Converts a time value in nanoseconds to a time value in seconds. - - `time_nanoseconds` is an `int` representing the number of nanoseconds since - the epoch. - - The returned value is a `float` representing the number of seconds since - the epoch. - """ - - return time_nanoseconds / 1e9 - - -def event_name_from_kv(key_values): - """A helper function which returns an event name from the given dict, or a - default event name. - """ - - if key_values is None or "event" not in key_values: - return DEFAULT_EVENT_NAME - - return key_values["event"] diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py deleted file mode 100644 index e7b342d64..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = "0.15.dev0" diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_shim.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_shim.py deleted file mode 100644 index 151ca07ba..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_shim.py +++ /dev/null @@ -1,636 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# TODO: make pylint use 3p opentracing module for type inference -# pylint:disable=no-member - -import time -from unittest import TestCase -from unittest.mock import Mock - -import opentracing - -from opentelemetry import propagators, trace -from opentelemetry.instrumentation.opentracing_shim import ( - SpanContextShim, - SpanShim, - create_tracer, - util, -) -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.test.mock_textmap import ( - MockTextMapPropagator, - NOOPTextMapPropagator, -) - - -class TestShim(TestCase): - # pylint: disable=too-many-public-methods - - def setUp(self): - """Create an OpenTelemetry tracer and a shim before every test case.""" - trace.set_tracer_provider(TracerProvider()) - self.shim = create_tracer(trace.get_tracer_provider()) - - @classmethod - def setUpClass(cls): - # Save current propagator to be restored on teardown. - cls._previous_propagator = propagators.get_global_textmap() - - # Set mock propagator for testing. - propagators.set_global_textmap(MockTextMapPropagator()) - - @classmethod - def tearDownClass(cls): - # Restore previous propagator. - propagators.set_global_textmap(cls._previous_propagator) - - def test_shim_type(self): - # Verify shim is an OpenTracing tracer. - self.assertIsInstance(self.shim, opentracing.Tracer) - - def test_start_active_span(self): - """Test span creation and activation using `start_active_span()`.""" - - with self.shim.start_active_span("TestSpan0") as scope: - # Verify correct type of Scope and Span objects. - self.assertIsInstance(scope, opentracing.Scope) - self.assertIsInstance(scope.span, opentracing.Span) - - # Verify span is started. - self.assertIsNotNone(scope.span.unwrap().start_time) - - # Verify span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - scope.span.context.unwrap(), - ) - # TODO: We can't check for equality of self.shim.active_span and - # scope.span because the same OpenTelemetry span is returned inside - # different SpanShim objects. A possible solution is described - # here: - # https://github.com/open-telemetry/opentelemetry-python/issues/161#issuecomment-534136274 - - # Verify span has ended. - self.assertIsNotNone(scope.span.unwrap().end_time) - - # Verify no span is active. - self.assertIsNone(self.shim.active_span) - - def test_start_span(self): - """Test span creation using `start_span()`.""" - - with self.shim.start_span("TestSpan1") as span: - # Verify correct type of Span object. - self.assertIsInstance(span, opentracing.Span) - - # Verify span is started. - self.assertIsNotNone(span.unwrap().start_time) - - # Verify `start_span()` does NOT make the span active. - self.assertIsNone(self.shim.active_span) - - # Verify span has ended. - self.assertIsNotNone(span.unwrap().end_time) - - def test_start_span_no_contextmanager(self): - """Test `start_span()` without a `with` statement.""" - - span = self.shim.start_span("TestSpan2") - - # Verify span is started. - self.assertIsNotNone(span.unwrap().start_time) - - # Verify `start_span()` does NOT make the span active. - self.assertIsNone(self.shim.active_span) - - span.finish() - - def test_explicit_span_finish(self): - """Test `finish()` method on `Span` objects.""" - - span = self.shim.start_span("TestSpan3") - - # Verify span hasn't ended. - self.assertIsNone(span.unwrap().end_time) - - span.finish() - - # Verify span has ended. - self.assertIsNotNone(span.unwrap().end_time) - - def test_explicit_start_time(self): - """Test `start_time` argument.""" - - now = time.time() - with self.shim.start_active_span("TestSpan4", start_time=now) as scope: - result = util.time_seconds_from_ns(scope.span.unwrap().start_time) - # Tolerate inaccuracies of less than a microsecond. See Note: - # https://open-telemetry.github.io/opentelemetry-python/opentelemetry.instrumentation.opentracing_shim.html - # TODO: This seems to work consistently, but we should find out the - # biggest possible loss of precision. - self.assertAlmostEqual(result, now, places=6) - - def test_explicit_end_time(self): - """Test `end_time` argument of `finish()` method.""" - - span = self.shim.start_span("TestSpan5") - now = time.time() - span.finish(now) - - end_time = util.time_seconds_from_ns(span.unwrap().end_time) - # Tolerate inaccuracies of less than a microsecond. See Note: - # https://open-telemetry.github.io/opentelemetry-python/opentelemetry.instrumentation.opentracing_shim.html - # TODO: This seems to work consistently, but we should find out the - # biggest possible loss of precision. - self.assertAlmostEqual(end_time, now, places=6) - - def test_explicit_span_activation(self): - """Test manual activation and deactivation of a span.""" - - span = self.shim.start_span("TestSpan6") - - # Verify no span is currently active. - self.assertIsNone(self.shim.active_span) - - with self.shim.scope_manager.activate( - span, finish_on_close=True - ) as scope: - # Verify span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - scope.span.context.unwrap(), - ) - - # Verify no span is active. - self.assertIsNone(self.shim.active_span) - - def test_start_active_span_finish_on_close(self): - """Test `finish_on_close` argument of `start_active_span()`.""" - - with self.shim.start_active_span( - "TestSpan7", finish_on_close=True - ) as scope: - # Verify span hasn't ended. - self.assertIsNone(scope.span.unwrap().end_time) - - # Verify span has ended. - self.assertIsNotNone(scope.span.unwrap().end_time) - - with self.shim.start_active_span( - "TestSpan8", finish_on_close=False - ) as scope: - # Verify span hasn't ended. - self.assertIsNone(scope.span.unwrap().end_time) - - # Verify span hasn't ended after scope had been closed. - self.assertIsNone(scope.span.unwrap().end_time) - - scope.span.finish() - - def test_activate_finish_on_close(self): - """Test `finish_on_close` argument of `activate()`.""" - - span = self.shim.start_span("TestSpan9") - - with self.shim.scope_manager.activate( - span, finish_on_close=True - ) as scope: - # Verify span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - scope.span.context.unwrap(), - ) - - # Verify span has ended. - self.assertIsNotNone(span.unwrap().end_time) - - span = self.shim.start_span("TestSpan10") - - with self.shim.scope_manager.activate( - span, finish_on_close=False - ) as scope: - # Verify span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - scope.span.context.unwrap(), - ) - - # Verify span hasn't ended. - self.assertIsNone(span.unwrap().end_time) - - span.finish() - - def test_explicit_scope_close(self): - """Test `close()` method on `ScopeShim`.""" - - with self.shim.start_active_span("ParentSpan") as parent: - # Verify parent span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - parent.span.context.unwrap(), - ) - - child = self.shim.start_active_span("ChildSpan") - - # Verify child span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - child.span.context.unwrap(), - ) - - # Verify child span hasn't ended. - self.assertIsNone(child.span.unwrap().end_time) - - child.close() - - # Verify child span has ended. - self.assertIsNotNone(child.span.unwrap().end_time) - - # Verify parent span becomes active again. - self.assertEqual( - self.shim.active_span.context.unwrap(), - parent.span.context.unwrap(), - ) - - def test_parent_child_implicit(self): - """Test parent-child relationship and activation/deactivation of spans - without specifying the parent span upon creation. - """ - - with self.shim.start_active_span("ParentSpan") as parent: - # Verify parent span is the active span. - self.assertEqual( - self.shim.active_span.context.unwrap(), - parent.span.context.unwrap(), - ) - - with self.shim.start_active_span("ChildSpan") as child: - # Verify child span is the active span. - self.assertEqual( - self.shim.active_span.context.unwrap(), - child.span.context.unwrap(), - ) - - # Verify parent-child relationship. - parent_trace_id = ( - parent.span.unwrap().get_span_context().trace_id - ) - child_trace_id = ( - child.span.unwrap().get_span_context().trace_id - ) - - self.assertEqual(parent_trace_id, child_trace_id) - self.assertEqual( - child.span.unwrap().parent, - parent.span.unwrap().get_span_context(), - ) - - # Verify parent span becomes the active span again. - self.assertEqual( - self.shim.active_span.context.unwrap(), - parent.span.context.unwrap() - # TODO: Check equality of the spans themselves rather than - # their context once the SpanShim reconstruction problem has - # been addressed (see previous TODO). - ) - - # Verify there is no active span. - self.assertIsNone(self.shim.active_span) - - def test_parent_child_explicit_span(self): - """Test parent-child relationship of spans when specifying a `Span` - object as a parent upon creation. - """ - - with self.shim.start_span("ParentSpan") as parent: - with self.shim.start_active_span( - "ChildSpan", child_of=parent - ) as child: - parent_trace_id = parent.unwrap().get_span_context().trace_id - child_trace_id = ( - child.span.unwrap().get_span_context().trace_id - ) - - self.assertEqual(child_trace_id, parent_trace_id) - self.assertEqual( - child.span.unwrap().parent, - parent.unwrap().get_span_context(), - ) - - with self.shim.start_span("ParentSpan") as parent: - child = self.shim.start_span("ChildSpan", child_of=parent) - - parent_trace_id = parent.unwrap().get_span_context().trace_id - child_trace_id = child.unwrap().get_span_context().trace_id - - self.assertEqual(child_trace_id, parent_trace_id) - self.assertEqual( - child.unwrap().parent, parent.unwrap().get_span_context() - ) - - child.finish() - - def test_parent_child_explicit_span_context(self): - """Test parent-child relationship of spans when specifying a - `SpanContext` object as a parent upon creation. - """ - - with self.shim.start_span("ParentSpan") as parent: - with self.shim.start_active_span( - "ChildSpan", child_of=parent.context - ) as child: - parent_trace_id = parent.unwrap().get_span_context().trace_id - child_trace_id = ( - child.span.unwrap().get_span_context().trace_id - ) - - self.assertEqual(child_trace_id, parent_trace_id) - self.assertEqual( - child.span.unwrap().parent, parent.context.unwrap() - ) - - with self.shim.start_span("ParentSpan") as parent: - with self.shim.start_span( - "SpanWithContextParent", child_of=parent.context - ) as child: - parent_trace_id = parent.unwrap().get_span_context().trace_id - child_trace_id = child.unwrap().get_span_context().trace_id - - self.assertEqual(child_trace_id, parent_trace_id) - self.assertEqual( - child.unwrap().parent, parent.context.unwrap() - ) - - def test_references(self): - """Test span creation using the `references` argument.""" - - with self.shim.start_span("ParentSpan") as parent: - ref = opentracing.child_of(parent.context) - - with self.shim.start_active_span( - "ChildSpan", references=[ref] - ) as child: - self.assertEqual( - child.span.unwrap().links[0].context, - parent.context.unwrap(), - ) - - def test_set_operation_name(self): - """Test `set_operation_name()` method.""" - - with self.shim.start_active_span("TestName") as scope: - self.assertEqual(scope.span.unwrap().name, "TestName") - - scope.span.set_operation_name("NewName") - self.assertEqual(scope.span.unwrap().name, "NewName") - - def test_tags(self): - """Test tags behavior using the `tags` argument and the `set_tags()` - method. - """ - - tags = {"foo": "bar"} - with self.shim.start_active_span("TestSetTag", tags=tags) as scope: - scope.span.set_tag("baz", "qux") - - self.assertEqual(scope.span.unwrap().attributes["foo"], "bar") - self.assertEqual(scope.span.unwrap().attributes["baz"], "qux") - - def test_span_tracer(self): - """Test the `tracer` property on `Span` objects.""" - - with self.shim.start_active_span("TestSpan11") as scope: - self.assertEqual(scope.span.tracer, self.shim) - - def test_log_kv(self): - """Test the `log_kv()` method on `Span` objects.""" - - with self.shim.start_span("TestSpan12") as span: - span.log_kv({"foo": "bar"}) - self.assertEqual(span.unwrap().events[0].attributes["foo"], "bar") - # Verify timestamp was generated automatically. - self.assertIsNotNone(span.unwrap().events[0].timestamp) - - # Test explicit timestamp. - now = time.time() - span.log_kv({"foo": "bar"}, now) - result = util.time_seconds_from_ns( - span.unwrap().events[1].timestamp - ) - self.assertEqual(span.unwrap().events[1].attributes["foo"], "bar") - # Tolerate inaccuracies of less than a microsecond. See Note: - # https://open-telemetry.github.io/opentelemetry-python/instrumentation/opentracing_shim/opentracing_shim.html - # TODO: This seems to work consistently, but we should find out the - # biggest possible loss of precision. - self.assertAlmostEqual(result, now, places=6) - - def test_log(self): - """Test the deprecated `log` method on `Span` objects.""" - - with self.shim.start_span("TestSpan13") as span: - with self.assertWarns(DeprecationWarning): - span.log(event="foo", payload="bar") - - self.assertEqual(span.unwrap().events[0].attributes["event"], "foo") - self.assertEqual(span.unwrap().events[0].attributes["payload"], "bar") - self.assertIsNotNone(span.unwrap().events[0].timestamp) - - def test_log_event(self): - """Test the deprecated `log_event` method on `Span` objects.""" - - with self.shim.start_span("TestSpan14") as span: - with self.assertWarns(DeprecationWarning): - span.log_event("foo", "bar") - - self.assertEqual(span.unwrap().events[0].attributes["event"], "foo") - self.assertEqual(span.unwrap().events[0].attributes["payload"], "bar") - self.assertIsNotNone(span.unwrap().events[0].timestamp) - - def test_span_context(self): - """Test construction of `SpanContextShim` objects.""" - - otel_context = trace.SpanContext(1234, 5678, is_remote=False) - context = SpanContextShim(otel_context) - - self.assertIsInstance(context, opentracing.SpanContext) - self.assertEqual(context.unwrap().trace_id, 1234) - self.assertEqual(context.unwrap().span_id, 5678) - - def test_span_on_error(self): - """Verify error tag and logs are created on span when an exception is - raised. - """ - - # Raise an exception while a span is active. - with self.assertRaises(Exception): - with self.shim.start_active_span("TestName") as scope: - raise Exception - - # Verify exception details have been added to span. - self.assertEqual(scope.span.unwrap().attributes["error"], True) - - def test_inject_http_headers(self): - """Test `inject()` method for Format.HTTP_HEADERS.""" - - otel_context = trace.SpanContext( - trace_id=1220, span_id=7478, is_remote=False - ) - context = SpanContextShim(otel_context) - - headers = {} - self.shim.inject(context, opentracing.Format.HTTP_HEADERS, headers) - self.assertEqual( - headers[MockTextMapPropagator.TRACE_ID_KEY], str(1220) - ) - self.assertEqual(headers[MockTextMapPropagator.SPAN_ID_KEY], str(7478)) - - def test_inject_text_map(self): - """Test `inject()` method for Format.TEXT_MAP.""" - - otel_context = trace.SpanContext( - trace_id=1220, span_id=7478, is_remote=False - ) - context = SpanContextShim(otel_context) - - # Verify Format.TEXT_MAP - text_map = {} - self.shim.inject(context, opentracing.Format.TEXT_MAP, text_map) - self.assertEqual( - text_map[MockTextMapPropagator.TRACE_ID_KEY], str(1220) - ) - self.assertEqual( - text_map[MockTextMapPropagator.SPAN_ID_KEY], str(7478) - ) - - def test_inject_binary(self): - """Test `inject()` method for Format.BINARY.""" - - otel_context = trace.SpanContext( - trace_id=1220, span_id=7478, is_remote=False - ) - context = SpanContextShim(otel_context) - - # Verify exception for non supported binary format. - with self.assertRaises(opentracing.UnsupportedFormatException): - self.shim.inject(context, opentracing.Format.BINARY, bytearray()) - - def test_extract_http_headers(self): - """Test `extract()` method for Format.HTTP_HEADERS.""" - - carrier = { - MockTextMapPropagator.TRACE_ID_KEY: 1220, - MockTextMapPropagator.SPAN_ID_KEY: 7478, - } - - ctx = self.shim.extract(opentracing.Format.HTTP_HEADERS, carrier) - self.assertEqual(ctx.unwrap().trace_id, 1220) - self.assertEqual(ctx.unwrap().span_id, 7478) - - def test_extract_empty_context_returns_invalid_context(self): - """In the case where the propagator cannot extract a - SpanContext, extract should return and invalid span context. - """ - _old_propagator = propagators.get_global_textmap() - propagators.set_global_textmap(NOOPTextMapPropagator()) - try: - carrier = {} - - ctx = self.shim.extract(opentracing.Format.HTTP_HEADERS, carrier) - self.assertEqual(ctx.unwrap(), trace.INVALID_SPAN_CONTEXT) - finally: - propagators.set_global_textmap(_old_propagator) - - def test_extract_text_map(self): - """Test `extract()` method for Format.TEXT_MAP.""" - - carrier = { - MockTextMapPropagator.TRACE_ID_KEY: 1220, - MockTextMapPropagator.SPAN_ID_KEY: 7478, - } - - ctx = self.shim.extract(opentracing.Format.TEXT_MAP, carrier) - self.assertEqual(ctx.unwrap().trace_id, 1220) - self.assertEqual(ctx.unwrap().span_id, 7478) - - def test_extract_binary(self): - """Test `extract()` method for Format.BINARY.""" - - # Verify exception for non supported binary format. - with self.assertRaises(opentracing.UnsupportedFormatException): - self.shim.extract(opentracing.Format.BINARY, bytearray()) - - def test_baggage(self): - - span_context_shim = SpanContextShim( - trace.SpanContext(1234, 5678, is_remote=False) - ) - - baggage = span_context_shim.baggage - - with self.assertRaises(ValueError): - baggage[1] = 3 - - span_shim = SpanShim(Mock(), span_context_shim, Mock()) - - span_shim.set_baggage_item(1, 2) - - self.assertTrue(span_shim.get_baggage_item(1), 2) - - def test_active(self): - """Test that the active property and start_active_span return the same - object""" - - # Verify no span is currently active. - self.assertIsNone(self.shim.active_span) - - with self.shim.start_active_span("TestSpan15") as scope: - # Verify span is active. - self.assertEqual( - self.shim.active_span.context.unwrap(), - scope.span.context.unwrap(), - ) - - self.assertIs(self.shim.scope_manager.active, scope) - - # Verify no span is active. - self.assertIsNone(self.shim.active_span) - - def test_mixed_mode(self): - """Test that span parent-child relationship is kept between - OpenTelemetry and the OpenTracing shim""" - - span_shim = self.shim.start_span("TestSpan16") - - with self.shim.scope_manager.activate(span_shim, finish_on_close=True): - - with ( - TracerProvider() - .get_tracer(__name__) - .start_as_current_span("abc") - ) as opentelemetry_span: - - self.assertIs( - span_shim.unwrap().context, opentelemetry_span.parent, - ) - - with ( - TracerProvider().get_tracer(__name__).start_as_current_span("abc") - ) as opentelemetry_span: - - with self.shim.start_active_span("TestSpan17") as scope: - - self.assertIs( - scope.span.unwrap().parent, opentelemetry_span.context, - ) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_util.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_util.py deleted file mode 100644 index 806a8da60..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/test_util.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -import unittest - -from opentelemetry.instrumentation.opentracing_shim import util -from opentelemetry.util import time_ns - - -class TestUtil(unittest.TestCase): - def test_event_name_from_kv(self): - # Test basic behavior. - event_name = "send HTTP request" - res = util.event_name_from_kv({"event": event_name, "foo": "bar"}) - self.assertEqual(res, event_name) - - # Test None. - res = util.event_name_from_kv(None) - self.assertEqual(res, util.DEFAULT_EVENT_NAME) - - # Test empty dict. - res = util.event_name_from_kv({}) - self.assertEqual(res, util.DEFAULT_EVENT_NAME) - - # Test missing `event` field. - res = util.event_name_from_kv({"foo": "bar"}) - self.assertEqual(res, util.DEFAULT_EVENT_NAME) - - def test_time_seconds_to_ns(self): - time_seconds = time.time() - result = util.time_seconds_to_ns(time_seconds) - - self.assertEqual(result, int(time_seconds * 1e9)) - - def test_time_seconds_from_ns(self): - time_nanoseconds = time_ns() - result = util.time_seconds_from_ns(time_nanoseconds) - - self.assertEqual(result, time_nanoseconds / 1e9) - - def test_time_conversion_precision(self): - """Verify time conversion from seconds to nanoseconds and vice versa is - accurate enough. - """ - - time_seconds = 1570484241.9501917 - time_nanoseconds = util.time_seconds_to_ns(time_seconds) - result = util.time_seconds_from_ns(time_nanoseconds) - - # Tolerate inaccuracies of less than a microsecond. - # TODO: Put a link to an explanation in the docs. - # TODO: This seems to work consistently, but we should find out the - # biggest possible loss of precision. - self.assertAlmostEqual(result, time_seconds, places=6) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/README.rst deleted file mode 100644 index ba7119cd6..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/README.rst +++ /dev/null @@ -1,47 +0,0 @@ - -Testbed suite for the OpenTelemetry-OpenTracing Bridge -====================================================== - -Testbed suite designed to test the API changes. - -Build and test. ---------------- - -.. code-block:: sh - - tox -e py37-test-opentracing-shim - -Alternatively, due to the organization of the suite, it's possible to run directly the tests using ``py.test``\ : - -.. code-block:: sh - - py.test -s testbed/test_multiple_callbacks/test_threads.py - -Tested frameworks ------------------ - -Currently the examples cover ``threading`` and ``asyncio``. - -List of patterns ----------------- - - -* `Active Span replacement `_ - Start an isolated task and query for its results in another task/thread. -* `Client-Server `_ - Typical client-server example. -* `Common Request Handler `_ - One request handler for all requests. -* `Late Span finish `_ - Late parent ``Span`` finish. -* `Multiple callbacks `_ - Multiple callbacks spawned at the same time. -* `Nested callbacks `_ - One callback at a time, defined in a pipeline fashion. -* `Subtask Span propagation `_ - ``Span`` propagation for subtasks/coroutines. - -Adding new patterns -------------------- - -A new pattern is composed of a directory under *testbed* with the *test_* prefix, and containing the files for each platform, also with the *test_* prefix: - -.. code-block:: - - testbed/ - test_new_pattern/ - test_threads.py - test_asyncio.py diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/otel_ot_shim_tracer.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/otel_ot_shim_tracer.py deleted file mode 100644 index c12bbfa02..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/otel_ot_shim_tracer.py +++ /dev/null @@ -1,26 +0,0 @@ -import opentelemetry.instrumentation.opentracing_shim as opentracingshim -from opentelemetry.sdk import trace -from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor -from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( - InMemorySpanExporter, -) - - -class MockTracer(opentracingshim.TracerShim): - """Wrapper of `opentracingshim.TracerShim`. - - MockTracer extends `opentracingshim.TracerShim` by adding a in memory - span exporter that can be used to get the list of finished spans.""" - - def __init__(self): - tracer_provider = trace.TracerProvider() - oteltracer = tracer_provider.get_tracer(__name__) - super(MockTracer, self).__init__(oteltracer) - exporter = InMemorySpanExporter() - span_processor = SimpleExportSpanProcessor(exporter) - tracer_provider.add_span_processor(span_processor) - - self.exporter = exporter - - def finished_spans(self): - return self.exporter.get_finished_spans() diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/README.rst deleted file mode 100644 index 6bb4d2f35..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/README.rst +++ /dev/null @@ -1,20 +0,0 @@ - -Active Span replacement example. -================================ - -This example shows a ``Span`` being created and then passed to an asynchronous task, which will temporary activate it to finish its processing, and further restore the previously active ``Span``. - -``threading`` implementation: - -.. code-block:: python - - # Create a new Span for this task - with self.tracer.start_active_span("task"): - - with self.tracer.scope_manager.activate(span, True): - # Simulate work strictly related to the initial Span - pass - - # Use the task span as parent of a new subtask - with self.tracer.start_active_span("subtask"): - pass diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_asyncio.py deleted file mode 100644 index cb555dc10..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_asyncio.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import print_function - -import asyncio - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import stop_loop_when - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - # Start an isolated task and query for its result -and finish it- - # in another task/thread - span = self.tracer.start_span("initial") - self.submit_another_task(span) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) >= 3, - timeout=5.0, - ) - self.loop.run_forever() - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - self.assertNamesEqual(spans, ["initial", "subtask", "task"]) - - # task/subtask are part of the same trace, - # and subtask is a child of task - self.assertSameTrace(spans[1], spans[2]) - self.assertIsChildOf(spans[1], spans[2]) - - # initial task is not related in any way to those two tasks - self.assertNotSameTrace(spans[0], spans[1]) - self.assertEqual(spans[0].parent, None) - - async def task(self, span): - # Create a new Span for this task - with self.tracer.start_active_span("task"): - - with self.tracer.scope_manager.activate(span, True): - # Simulate work strictly related to the initial Span - pass - - # Use the task span as parent of a new subtask - with self.tracer.start_active_span("subtask"): - pass - - def submit_another_task(self, span): - self.loop.create_task(self.task(span)) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_threads.py deleted file mode 100644 index e382d5d71..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_active_span_replacement/test_threads.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import print_function - -from concurrent.futures import ThreadPoolExecutor - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - # use max_workers=3 as a general example even if only one would suffice - self.executor = ThreadPoolExecutor(max_workers=3) - - def test_main(self): - # Start an isolated task and query for its result -and finish it- - # in another task/thread - span = self.tracer.start_span("initial") - self.submit_another_task(span) - - self.executor.shutdown(True) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - self.assertNamesEqual(spans, ["initial", "subtask", "task"]) - - # task/subtask are part of the same trace, - # and subtask is a child of task - self.assertSameTrace(spans[1], spans[2]) - self.assertIsChildOf(spans[1], spans[2]) - - # initial task is not related in any way to those two tasks - self.assertNotSameTrace(spans[0], spans[1]) - self.assertEqual(spans[0].parent, None) - self.assertEqual(spans[2].parent, None) - - def task(self, span): - # Create a new Span for this task - with self.tracer.start_active_span("task"): - - with self.tracer.scope_manager.activate(span, True): - # Simulate work strictly related to the initial Span - pass - - # Use the task span as parent of a new subtask - with self.tracer.start_active_span("subtask"): - pass - - def submit_another_task(self, span): - self.executor.submit(self.task, span) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/README.rst deleted file mode 100644 index 730fd9295..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/README.rst +++ /dev/null @@ -1,19 +0,0 @@ - -Client-Server example. -====================== - -This example shows a ``Span`` created by a ``Client``, which will send a ``Message`` / ``SpanContext`` to a ``Server``, which will in turn extract such context and use it as parent of a new (server-side) ``Span``. - -``Client.send()`` is used to send messages and inject the ``SpanContext`` using the ``TEXT_MAP`` format, and ``Server.process()`` will process received messages and will extract the context used as parent. - -.. code-block:: python - - def send(self): - with self.tracer.start_active_span("send") as scope: - scope.span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - message = {} - self.tracer.inject(scope.span.context, - opentracing.Format.TEXT_MAP, - message) - self.queue.put(message) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_asyncio.py deleted file mode 100644 index 537958471..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_asyncio.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import print_function - -import asyncio - -import opentracing -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_logger, get_one_by_tag, stop_loop_when - -logger = get_logger(__name__) - - -class Server: - def __init__(self, *args, **kwargs): - tracer = kwargs.pop("tracer") - queue = kwargs.pop("queue") - super(Server, self).__init__(*args, **kwargs) - - self.tracer = tracer - self.queue = queue - - async def run(self): - value = await self.queue.get() - self.process(value) - - def process(self, message): - logger.info("Processing message in server") - - ctx = self.tracer.extract(opentracing.Format.TEXT_MAP, message) - with self.tracer.start_active_span("receive", child_of=ctx) as scope: - scope.span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER) - - -class Client: - def __init__(self, tracer, queue): - self.tracer = tracer - self.queue = queue - - async def send(self): - with self.tracer.start_active_span("send") as scope: - scope.span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - message = {} - self.tracer.inject( - scope.span.context, opentracing.Format.TEXT_MAP, message - ) - await self.queue.put(message) - - logger.info("Sent message from client") - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.queue = asyncio.Queue() - self.loop = asyncio.get_event_loop() - self.server = Server(tracer=self.tracer, queue=self.queue) - - def test(self): - client = Client(self.tracer, self.queue) - self.loop.create_task(self.server.run()) - self.loop.create_task(client.send()) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) >= 2, - timeout=5.0, - ) - self.loop.run_forever() - - spans = self.tracer.finished_spans() - self.assertIsNotNone( - get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER) - ) - self.assertIsNotNone( - get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - ) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_threads.py deleted file mode 100644 index 619781ede..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_client_server/test_threads.py +++ /dev/null @@ -1,75 +0,0 @@ -from __future__ import print_function - -from queue import Queue -from threading import Thread - -import opentracing -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import await_until, get_logger, get_one_by_tag - -logger = get_logger(__name__) - - -class Server(Thread): - def __init__(self, *args, **kwargs): - tracer = kwargs.pop("tracer") - queue = kwargs.pop("queue") - super(Server, self).__init__(*args, **kwargs) - - self.daemon = True - self.tracer = tracer - self.queue = queue - - def run(self): - value = self.queue.get() - self.process(value) - - def process(self, message): - logger.info("Processing message in server") - - ctx = self.tracer.extract(opentracing.Format.TEXT_MAP, message) - with self.tracer.start_active_span("receive", child_of=ctx) as scope: - scope.span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER) - - -class Client: - def __init__(self, tracer, queue): - self.tracer = tracer - self.queue = queue - - def send(self): - with self.tracer.start_active_span("send") as scope: - scope.span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - message = {} - self.tracer.inject( - scope.span.context, opentracing.Format.TEXT_MAP, message - ) - self.queue.put(message) - - logger.info("Sent message from client") - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.queue = Queue() - self.server = Server(tracer=self.tracer, queue=self.queue) - self.server.start() - - def test(self): - client = Client(self.tracer, self.queue) - client.send() - - await_until(lambda: len(self.tracer.finished_spans()) >= 2) - - spans = self.tracer.finished_spans() - self.assertIsNotNone( - get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER) - ) - self.assertIsNotNone( - get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - ) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/README.rst deleted file mode 100644 index 1bcda539b..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/README.rst +++ /dev/null @@ -1,23 +0,0 @@ - -Common Request Handler example. -=============================== - -This example shows a ``Span`` used with ``RequestHandler``, which is used as a middleware (as in web frameworks) to manage a new ``Span`` per operation through its ``before_request()`` / ``after_response()`` methods. - -Implementation details: - - -* For ``threading``, no active ``Span`` is consumed as the tasks may be run concurrently on different threads, and an explicit ``SpanContext`` has to be saved to be used as parent. - -RequestHandler implementation: - -.. code-block:: python - - def before_request(self, request, request_context): - - # If we should ignore the active Span, use any passed SpanContext - # as the parent. Else, use the active one. - span = self.tracer.start_span("send", - child_of=self.context, - ignore_active_span=True) - diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/request_handler.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/request_handler.py deleted file mode 100644 index 47ff08802..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/request_handler.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import print_function - -from opentracing.ext import tags - -from ..utils import get_logger - -logger = get_logger(__name__) - - -class RequestHandler: - def __init__(self, tracer, context=None, ignore_active_span=True): - self.tracer = tracer - self.context = context - self.ignore_active_span = ignore_active_span - - def before_request(self, request, request_context): - logger.info("Before request %s", request) - - # If we should ignore the active Span, use any passed SpanContext - # as the parent. Else, use the active one. - if self.ignore_active_span: - span = self.tracer.start_span( - "send", child_of=self.context, ignore_active_span=True - ) - else: - span = self.tracer.start_span("send") - - span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - request_context["span"] = span - - def after_request(self, request, request_context): - # pylint: disable=no-self-use - logger.info("After request %s", request) - - span = request_context.get("span") - if span is not None: - span.finish() diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_asyncio.py deleted file mode 100644 index b0216dd75..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_asyncio.py +++ /dev/null @@ -1,136 +0,0 @@ -from __future__ import print_function - -import asyncio - -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_logger, get_one_by_operation_name, stop_loop_when -from .request_handler import RequestHandler - -logger = get_logger(__name__) - - -class Client: - def __init__(self, request_handler, loop): - self.request_handler = request_handler - self.loop = loop - - async def send_task(self, message): - request_context = {} - - async def before_handler(): - self.request_handler.before_request(message, request_context) - - async def after_handler(): - self.request_handler.after_request(message, request_context) - - await before_handler() - await after_handler() - - return "%s::response" % message - - def send(self, message): - return self.send_task(message) - - def send_sync(self, message): - return self.loop.run_until_complete(self.send_task(message)) - - -class TestAsyncio(OpenTelemetryTestCase): - """ - There is only one instance of 'RequestHandler' per 'Client'. Methods of - 'RequestHandler' are executed in different Tasks, and no Span propagation - among them is done automatically. - Therefore we cannot use current active span and activate span. - So one issue here is setting correct parent span. - """ - - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - self.client = Client(RequestHandler(self.tracer), self.loop) - - def test_two_callbacks(self): - res_future1 = self.loop.create_task(self.client.send("message1")) - res_future2 = self.loop.create_task(self.client.send("message2")) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) >= 2, - timeout=5.0, - ) - self.loop.run_forever() - - self.assertEqual("message1::response", res_future1.result()) - self.assertEqual("message2::response", res_future2.result()) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - - for span in spans: - self.assertEqual( - span.attributes.get(tags.SPAN_KIND, None), - tags.SPAN_KIND_RPC_CLIENT, - ) - - self.assertNotSameTrace(spans[0], spans[1]) - self.assertIsNone(spans[0].parent) - self.assertIsNone(spans[1].parent) - - def test_parent_not_picked(self): - """Active parent should not be picked up by child.""" - - async def do_task(): - with self.tracer.start_active_span("parent"): - response = await self.client.send_task("no_parent") - self.assertEqual("no_parent::response", response) - - self.loop.run_until_complete(do_task()) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - - child_span = get_one_by_operation_name(spans, "send") - self.assertIsNotNone(child_span) - - parent_span = get_one_by_operation_name(spans, "parent") - self.assertIsNotNone(parent_span) - - # Here check that there is no parent-child relation. - self.assertIsNotChildOf(child_span, parent_span) - - def test_good_solution_to_set_parent(self): - """Asyncio and contextvars are integrated, in this case it is not needed - to activate current span by hand. - """ - - async def do_task(): - with self.tracer.start_active_span("parent"): - # Set ignore_active_span to False indicating that the - # framework will do it for us. - req_handler = RequestHandler( - self.tracer, ignore_active_span=False, - ) - client = Client(req_handler, self.loop) - response = await client.send_task("correct_parent") - - self.assertEqual("correct_parent::response", response) - - # Send second request, now there is no active parent, - # but it will be set, ups - response = await client.send_task("wrong_parent") - self.assertEqual("wrong_parent::response", response) - - self.loop.run_until_complete(do_task()) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - - spans = sorted(spans, key=lambda x: x.start_time) - parent_span = get_one_by_operation_name(spans, "parent") - self.assertIsNotNone(parent_span) - - self.assertIsChildOf(spans[1], parent_span) - self.assertIsNotChildOf(spans[2], parent_span) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_threads.py deleted file mode 100644 index 4ab8b2a07..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_common_request_handler/test_threads.py +++ /dev/null @@ -1,119 +0,0 @@ -from __future__ import print_function - -from concurrent.futures import ThreadPoolExecutor - -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_logger, get_one_by_operation_name -from .request_handler import RequestHandler - -logger = get_logger(__name__) - - -class Client: - def __init__(self, request_handler, executor): - self.request_handler = request_handler - self.executor = executor - - def send_task(self, message): - request_context = {} - - def before_handler(): - self.request_handler.before_request(message, request_context) - - def after_handler(): - self.request_handler.after_request(message, request_context) - - self.executor.submit(before_handler).result() - self.executor.submit(after_handler).result() - - return "%s::response" % message - - def send(self, message): - return self.executor.submit(self.send_task, message) - - def send_sync(self, message, timeout=5.0): - fut = self.executor.submit(self.send_task, message) - return fut.result(timeout=timeout) - - -class TestThreads(OpenTelemetryTestCase): - """ - There is only one instance of 'RequestHandler' per 'Client'. Methods of - 'RequestHandler' are executed concurrently in different threads which are - reused (executor). Therefore we cannot use current active span and - activate span. So one issue here is setting correct parent span. - """ - - def setUp(self): - self.tracer = MockTracer() - self.executor = ThreadPoolExecutor(max_workers=3) - self.client = Client(RequestHandler(self.tracer), self.executor) - - def test_two_callbacks(self): - response_future1 = self.client.send("message1") - response_future2 = self.client.send("message2") - - self.assertEqual("message1::response", response_future1.result(5.0)) - self.assertEqual("message2::response", response_future2.result(5.0)) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - - for span in spans: - self.assertEqual( - span.attributes.get(tags.SPAN_KIND, None), - tags.SPAN_KIND_RPC_CLIENT, - ) - - self.assertNotSameTrace(spans[0], spans[1]) - self.assertIsNone(spans[0].parent) - self.assertIsNone(spans[1].parent) - - def test_parent_not_picked(self): - """Active parent should not be picked up by child.""" - - with self.tracer.start_active_span("parent"): - response = self.client.send_sync("no_parent") - self.assertEqual("no_parent::response", response) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - - child_span = get_one_by_operation_name(spans, "send") - self.assertIsNotNone(child_span) - - parent_span = get_one_by_operation_name(spans, "parent") - self.assertIsNotNone(parent_span) - - # Here check that there is no parent-child relation. - self.assertIsNotChildOf(child_span, parent_span) - - def test_bad_solution_to_set_parent(self): - """Solution is bad because parent is per client and is not automatically - activated depending on the context. - """ - - with self.tracer.start_active_span("parent") as scope: - client = Client( - # Pass a span context to be used ad the parent. - RequestHandler(self.tracer, scope.span.context), - self.executor, - ) - response = client.send_sync("correct_parent") - self.assertEqual("correct_parent::response", response) - - response = client.send_sync("wrong_parent") - self.assertEqual("wrong_parent::response", response) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - - spans = sorted(spans, key=lambda x: x.start_time) - parent_span = get_one_by_operation_name(spans, "parent") - self.assertIsNotNone(parent_span) - - self.assertIsChildOf(spans[1], parent_span) - self.assertIsChildOf(spans[2], parent_span) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/README.rst deleted file mode 100644 index 8c4ffd864..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/README.rst +++ /dev/null @@ -1,18 +0,0 @@ - -Late Span finish example. -========================= - -This example shows a ``Span`` for a top-level operation, with independent, unknown lifetime, acting as parent of a few asynchronous subtasks (which must re-activate it but not finish it). - -.. code-block:: python - - # Fire away a few subtasks, passing a parent Span whose lifetime - # is not tied at all to the children. - def submit_subtasks(self, parent_span): - def task(name, interval): - with self.tracer.scope_manager.activate(parent_span, False): - with self.tracer.start_active_span(name): - time.sleep(interval) - - self.executor.submit(task, "task1", 0.1) - self.executor.submit(task, "task2", 0.3) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_asyncio.py deleted file mode 100644 index 128073b05..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_asyncio.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import print_function - -import asyncio - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_logger, stop_loop_when - -logger = get_logger(__name__) - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - # Create a Span and use it as (explicit) parent of a pair of subtasks. - parent_span = self.tracer.start_span("parent") - self.submit_subtasks(parent_span) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) >= 2, - timeout=5.0, - ) - self.loop.run_forever() - - # Late-finish the parent Span now. - parent_span.finish() - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - self.assertNamesEqual(spans, ["task1", "task2", "parent"]) - - for idx in range(2): - self.assertSameTrace(spans[idx], spans[-1]) - self.assertIsChildOf(spans[idx], spans[-1]) - self.assertTrue(spans[idx].end_time <= spans[-1].end_time) - - # Fire away a few subtasks, passing a parent Span whose lifetime - # is not tied at all to the children. - def submit_subtasks(self, parent_span): - async def task(name): - logger.info("Running %s", name) - with self.tracer.scope_manager.activate(parent_span, False): - with self.tracer.start_active_span(name): - await asyncio.sleep(0.1) - - self.loop.create_task(task("task1")) - self.loop.create_task(task("task2")) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_threads.py deleted file mode 100644 index 5972eb8b9..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_late_span_finish/test_threads.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import print_function - -import time -from concurrent.futures import ThreadPoolExecutor - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.executor = ThreadPoolExecutor(max_workers=3) - - def test_main(self): - # Create a Span and use it as (explicit) parent of a pair of subtasks. - parent_span = self.tracer.start_span("parent") - self.submit_subtasks(parent_span) - - # Wait for the threadpool to be done. - self.executor.shutdown(True) - - # Late-finish the parent Span now. - parent_span.finish() - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 3) - self.assertNamesEqual(spans, ["task1", "task2", "parent"]) - - for idx in range(2): - self.assertSameTrace(spans[idx], spans[-1]) - self.assertIsChildOf(spans[idx], spans[-1]) - self.assertTrue(spans[idx].end_time <= spans[-1].end_time) - - # Fire away a few subtasks, passing a parent Span whose lifetime - # is not tied at all to the children. - def submit_subtasks(self, parent_span): - def task(name, interval): - with self.tracer.scope_manager.activate(parent_span, False): - with self.tracer.start_active_span(name): - time.sleep(interval) - - self.executor.submit(task, "task1", 0.1) - self.executor.submit(task, "task2", 0.3) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/README.rst deleted file mode 100644 index 952d1ec51..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/README.rst +++ /dev/null @@ -1,19 +0,0 @@ - -Listener Response example. -========================== - -This example shows a ``Span`` created upon a message being sent to a ``Client``, and its handling along a related, **not shared** ``ResponseListener`` object with a ``on_response(self, response)`` method to finish it. - -.. code-block:: python - - def _task(self, message, listener): - res = "%s::response" % message - listener.on_response(res) - return res - - def send_sync(self, message): - span = self.tracer.start_span("send") - span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - listener = ResponseListener(span) - return self.executor.submit(self._task, message, listener).result() diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/response_listener.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/response_listener.py deleted file mode 100644 index dd143c20b..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/response_listener.py +++ /dev/null @@ -1,7 +0,0 @@ -class ResponseListener: - def __init__(self, span): - self.span = span - - def on_response(self, res): - del res - self.span.finish() diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_asyncio.py deleted file mode 100644 index 085c0ea81..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_asyncio.py +++ /dev/null @@ -1,45 +0,0 @@ -from __future__ import print_function - -import asyncio - -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_one_by_tag -from .response_listener import ResponseListener - - -class Client: - def __init__(self, tracer, loop): - self.tracer = tracer - self.loop = loop - - async def task(self, message, listener): - res = "%s::response" % message - listener.on_response(res) - return res - - def send_sync(self, message): - span = self.tracer.start_span("send") - span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - listener = ResponseListener(span) - return self.loop.run_until_complete(self.task(message, listener)) - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - client = Client(self.tracer, self.loop) - res = client.send_sync("message") - self.assertEqual(res, "message::response") - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 1) - - span = get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - self.assertIsNotNone(span) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_threads.py deleted file mode 100644 index 8f82e1fb1..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_listener_per_request/test_threads.py +++ /dev/null @@ -1,45 +0,0 @@ -from __future__ import print_function - -from concurrent.futures import ThreadPoolExecutor - -from opentracing.ext import tags - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_one_by_tag -from .response_listener import ResponseListener - - -class Client: - def __init__(self, tracer): - self.tracer = tracer - self.executor = ThreadPoolExecutor(max_workers=3) - - def _task(self, message, listener): - # pylint: disable=no-self-use - res = "%s::response" % message - listener.on_response(res) - return res - - def send_sync(self, message): - span = self.tracer.start_span("send") - span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - - listener = ResponseListener(span) - return self.executor.submit(self._task, message, listener).result() - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - - def test_main(self): - client = Client(self.tracer) - res = client.send_sync("message") - self.assertEqual(res, "message::response") - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 1) - - span = get_one_by_tag(spans, tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT) - self.assertIsNotNone(span) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/README.rst deleted file mode 100644 index 204f282cf..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/README.rst +++ /dev/null @@ -1,44 +0,0 @@ - -Multiple callbacks example. -=========================== - -This example shows a ``Span`` created for a top-level operation, covering a set of asynchronous operations (representing callbacks), and have this ``Span`` finished when **all** of them have been executed. - -``Client.send()`` is used to create a new asynchronous operation (callback), and in turn every operation both restores the active ``Span``, and creates a child ``Span`` (useful for measuring the performance of each callback). - -Implementation details: - - -* For ``threading``, a thread-safe counter is put in each ``Span`` to keep track of the pending callbacks, and call ``Span.finish()`` when the count becomes 0. -* For ``asyncio`` the children corotuines representing the subtasks are simply yielded over, so no counter is needed. - -``threading`` implementation: - -.. code-block:: python - - def task(self, interval, parent_span): - logger.info("Starting task") - - try: - scope = self.tracer.scope_manager.activate(parent_span, False) - with self.tracer.start_active_span("task"): - time.sleep(interval) - finally: - scope.close() - if parent_span._ref_count.decr() == 0: - parent_span.finish() - -``asyncio`` implementation: - -.. code-block:: python - - async def task(self, interval, parent_span): - logger.info("Starting task") - - with self.tracer.start_active_span("task"): - await asyncio.sleep(interval) - - # Invoke and yield over the corotuines. - with self.tracer.start_active_span("parent"): - tasks = self.submit_callbacks() - await asyncio.gather(*tasks) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_asyncio.py deleted file mode 100644 index 36043d0a9..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_asyncio.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import print_function - -import asyncio -import random - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import get_logger, stop_loop_when - -random.seed() -logger = get_logger(__name__) - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - # Need to run within a Task, as the scope manager depends - # on Task.current_task() - async def main_task(): - with self.tracer.start_active_span("parent"): - tasks = self.submit_callbacks() - await asyncio.gather(*tasks) - - self.loop.create_task(main_task()) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) >= 4, - timeout=5.0, - ) - self.loop.run_forever() - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 4) - self.assertNamesEqual(spans, ["task", "task", "task", "parent"]) - - for idx in range(3): - self.assertSameTrace(spans[idx], spans[-1]) - self.assertIsChildOf(spans[idx], spans[-1]) - - async def task(self, interval, parent_span): - logger.info("Starting task") - - with self.tracer.scope_manager.activate(parent_span, False): - with self.tracer.start_active_span("task"): - await asyncio.sleep(interval) - - def submit_callbacks(self): - parent_span = self.tracer.scope_manager.active.span - tasks = [] - for _ in range(3): - interval = 0.1 + random.randint(200, 500) * 0.001 - task = self.loop.create_task(self.task(interval, parent_span)) - tasks.append(task) - - return tasks diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_threads.py deleted file mode 100644 index b24ae643e..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_multiple_callbacks/test_threads.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import print_function - -import random -import time -from concurrent.futures import ThreadPoolExecutor - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import RefCount, get_logger - -random.seed() -logger = get_logger(__name__) - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.executor = ThreadPoolExecutor(max_workers=3) - - def test_main(self): - try: - scope = self.tracer.start_active_span( - "parent", finish_on_close=False - ) - scope.span.ref_count = RefCount(1) - self.submit_callbacks(scope.span) - finally: - scope.close() - if scope.span.ref_count.decr() == 0: - scope.span.finish() - - self.executor.shutdown(True) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 4) - self.assertNamesEqual(spans, ["task", "task", "task", "parent"]) - - for idx in range(3): - self.assertSameTrace(spans[idx], spans[-1]) - self.assertIsChildOf(spans[idx], spans[-1]) - - def task(self, interval, parent_span): - logger.info("Starting task") - - try: - scope = self.tracer.scope_manager.activate(parent_span, False) - with self.tracer.start_active_span("task"): - time.sleep(interval) - finally: - scope.close() - if parent_span.ref_count.decr() == 0: - parent_span.finish() - - def submit_callbacks(self, parent_span): - for _ in range(3): - parent_span.ref_count.incr() - self.executor.submit( - self.task, 0.1 + random.randint(200, 500) * 0.001, parent_span - ) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/README.rst deleted file mode 100644 index c191431cc..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/README.rst +++ /dev/null @@ -1,47 +0,0 @@ - -Nested callbacks example. -========================= - -This example shows a ``Span`` for a top-level operation, and how it can be passed down on a list of nested callbacks (always one at a time), have it as the active one for each of them, and finished **only** when the last one executes. For Python, we have decided to do it in a **fire-and-forget** fashion. - -Implementation details: - - -* For ``threading``, the ``Span`` is manually activatted it in each corotuine/task. -* For ``asyncio``, the active ``Span`` is not activated down the chain as the ``Context`` automatically propagates it. - -``threading`` implementation: - -.. code-block:: python - - def submit(self): - span = self.tracer.scope_manager.active.span - - def task1(): - with self.tracer.scope_manager.activate(span, False): - span.set_tag("key1", "1") - - def task2(): - with self.tracer.scope_manager.activate(span, False): - span.set_tag("key2", "2") - ... - -``asyncio`` implementation: - -.. code-block:: python - - async def task1(): - span.set_tag("key1", "1") - - async def task2(): - span.set_tag("key2", "2") - - async def task3(): - span.set_tag("key3", "3") - span.finish() - - self.loop.create_task(task3()) - - self.loop.create_task(task2()) - - self.loop.create_task(task1()) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_asyncio.py deleted file mode 100644 index 12eb43627..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_asyncio.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import print_function - -import asyncio - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import stop_loop_when - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - # Start a Span and let the callback-chain - # finish it when the task is done - async def task(): - with self.tracer.start_active_span("one", finish_on_close=False): - self.submit() - - self.loop.create_task(task()) - - stop_loop_when( - self.loop, - lambda: len(self.tracer.finished_spans()) == 1, - timeout=5.0, - ) - self.loop.run_forever() - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 1) - self.assertEqual(spans[0].name, "one") - - for idx in range(1, 4): - self.assertEqual( - spans[0].attributes.get("key%s" % idx, None), str(idx) - ) - - def submit(self): - span = self.tracer.scope_manager.active.span - - async def task1(): - span.set_tag("key1", "1") - - async def task2(): - span.set_tag("key2", "2") - - async def task3(): - span.set_tag("key3", "3") - span.finish() - - self.loop.create_task(task3()) - - self.loop.create_task(task2()) - - self.loop.create_task(task1()) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_threads.py deleted file mode 100644 index a1d35c35d..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_nested_callbacks/test_threads.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import print_function - -from concurrent.futures import ThreadPoolExecutor - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase -from ..utils import await_until - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.executor = ThreadPoolExecutor(max_workers=3) - - def tearDown(self): - self.executor.shutdown(False) - - def test_main(self): - # Start a Span and let the callback-chain - # finish it when the task is done - with self.tracer.start_active_span("one", finish_on_close=False): - self.submit() - - # Cannot shutdown the executor and wait for the callbacks - # to be run, as in such case only the first will be executed, - # and the rest will get canceled. - await_until(lambda: len(self.tracer.finished_spans()) == 1, 5) - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 1) - self.assertEqual(spans[0].name, "one") - - for idx in range(1, 4): - self.assertEqual( - spans[0].attributes.get("key%s" % idx, None), str(idx) - ) - - def submit(self): - span = self.tracer.scope_manager.active.span - - def task1(): - with self.tracer.scope_manager.activate(span, False): - span.set_tag("key1", "1") - - def task2(): - with self.tracer.scope_manager.activate(span, False): - span.set_tag("key2", "2") - - def task3(): - with self.tracer.scope_manager.activate( - span, True - ): - span.set_tag("key3", "3") - - self.executor.submit(task3) - - self.executor.submit(task2) - - self.executor.submit(task1) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/README.rst b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/README.rst deleted file mode 100644 index eaeda8e6f..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/README.rst +++ /dev/null @@ -1,42 +0,0 @@ - -Subtask Span propagation example. -================================= - -This example shows an active ``Span`` being simply propagated to the subtasks -either threads or coroutines-, and finished **by** the parent task. In real-life scenarios instrumentation libraries may help with ``Span`` propagation **if** not offered by default (see implementation details below), but we show here the case without such help. - -Implementation details: - -* For ``threading``, the ``Span`` is manually passed down the call chain, activating it in each corotuine/task. -* For ``asyncio``, the active ``Span`` is not passed nor activated down the chain as the ``Context`` automatically propagates it. - -``threading`` implementation: - -.. code-block:: python - - def parent_task(self, message): - with self.tracer.start_active_span("parent") as scope: - f = self.executor.submit(self.child_task, message, scope.span) - res = f.result() - - return res - - def child_task(self, message, span): - with self.tracer.scope_manager.activate(span, False): - with self.tracer.start_active_span("child"): - return "%s::response" % message - -``asyncio`` implementation: - -.. code-block:: python - - async def parent_task(self, message): # noqa - with self.tracer.start_active_span("parent"): - res = await self.child_task(message) - - return res - - async def child_task(self, message): - # No need to pass/activate the parent Span, as it stays in the context. - with self.tracer.start_active_span("child"): - return "%s::response" % message - diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/__init__.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_asyncio.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_asyncio.py deleted file mode 100644 index 6e5445607..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_asyncio.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import, print_function - -import asyncio - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase - - -class TestAsyncio(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.loop = asyncio.get_event_loop() - - def test_main(self): - res = self.loop.run_until_complete(self.parent_task("message")) - self.assertEqual(res, "message::response") - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - self.assertNamesEqual(spans, ["child", "parent"]) - self.assertIsChildOf(spans[0], spans[1]) - - async def parent_task(self, message): # noqa - with self.tracer.start_active_span("parent"): - res = await self.child_task(message) - - return res - - async def child_task(self, message): - # No need to pass/activate the parent Span, as it stays in the context. - with self.tracer.start_active_span("child"): - return "%s::response" % message diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_threads.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_threads.py deleted file mode 100644 index 1ba5f697c..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/test_subtask_span_propagation/test_threads.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import absolute_import, print_function - -from concurrent.futures import ThreadPoolExecutor - -from ..otel_ot_shim_tracer import MockTracer -from ..testcase import OpenTelemetryTestCase - - -class TestThreads(OpenTelemetryTestCase): - def setUp(self): - self.tracer = MockTracer() - self.executor = ThreadPoolExecutor(max_workers=3) - - def test_main(self): - res = self.executor.submit(self.parent_task, "message").result() - self.assertEqual(res, "message::response") - - spans = self.tracer.finished_spans() - self.assertEqual(len(spans), 2) - self.assertNamesEqual(spans, ["child", "parent"]) - self.assertIsChildOf(spans[0], spans[1]) - - def parent_task(self, message): - with self.tracer.start_active_span("parent") as scope: - fut = self.executor.submit(self.child_task, message, scope.span) - res = fut.result() - - return res - - def child_task(self, message, span): - with self.tracer.scope_manager.activate(span, False): - with self.tracer.start_active_span("child"): - return "%s::response" % message diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/testcase.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/testcase.py deleted file mode 100644 index c1ce6ea5a..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/testcase.py +++ /dev/null @@ -1,46 +0,0 @@ -import unittest - -import opentelemetry.trace as trace_api - - -# pylint: disable=C0103 -class OpenTelemetryTestCase(unittest.TestCase): - def assertSameTrace(self, spanA, spanB): - return self.assertEqual(spanA.context.trace_id, spanB.context.trace_id) - - def assertNotSameTrace(self, spanA, spanB): - return self.assertNotEqual( - spanA.context.trace_id, spanB.context.trace_id - ) - - def assertIsChildOf(self, spanA, spanB): - # spanA is child of spanB - self.assertIsNotNone(spanA.parent) - - ctxA = spanA.parent - if isinstance(spanA.parent, trace_api.Span): - ctxA = spanA.parent.context - - ctxB = spanB - if isinstance(ctxB, trace_api.Span): - ctxB = spanB.context - - return self.assertEqual(ctxA.span_id, ctxB.span_id) - - def assertIsNotChildOf(self, spanA, spanB): - # spanA is NOT child of spanB - if spanA.parent is None: - return - - ctxA = spanA.parent - if isinstance(spanA.parent, trace_api.Span): - ctxA = spanA.parent.context - - ctxB = spanB - if isinstance(ctxB, trace_api.Span): - ctxB = spanB.context - - self.assertNotEqual(ctxA.span_id, ctxB.span_id) - - def assertNamesEqual(self, spans, names): - self.assertEqual(list(map(lambda x: x.name, spans)), names) diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/utils.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/utils.py deleted file mode 100644 index a7b977f3d..000000000 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/tests/testbed/utils.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import print_function - -import logging -import threading -import time - - -class RefCount: - """Thread-safe counter""" - - def __init__(self, count=1): - self._lock = threading.Lock() - self._count = count - - def incr(self): - with self._lock: - self._count += 1 - return self._count - - def decr(self): - with self._lock: - self._count -= 1 - return self._count - - -def await_until(func, timeout=5.0): - """Polls for func() to return True""" - end_time = time.time() + timeout - while time.time() < end_time and not func(): - time.sleep(0.01) - - -def stop_loop_when(loop, cond_func, timeout=5.0): - """ - Registers a periodic callback that stops the loop when cond_func() == True. - Compatible with both Tornado and asyncio. - """ - if cond_func() or timeout <= 0.0: - loop.stop() - return - - timeout -= 0.1 - loop.call_later(0.1, stop_loop_when, loop, cond_func, timeout) - - -def get_logger(name): - """Returns a logger with log level set to INFO""" - logging.basicConfig(level=logging.INFO) - return logging.getLogger(name) - - -def get_one_by_tag(spans, key, value): - """Return a single Span with a tag value/key from a list, - errors if more than one is found.""" - - found = [] - for span in spans: - if span.attributes.get(key) == value: - found.append(span) - - if len(found) > 1: - raise RuntimeError("Too many values") - - return found[0] if len(found) > 0 else None - - -def get_one_by_operation_name(spans, name): - """Return a single Span with a name from a list, - errors if more than one is found.""" - found = [] - for span in spans: - if span.name == name: - found.append(span) - - if len(found) > 1: - raise RuntimeError("Too many values") - - return found[0] if len(found) > 0 else None