diff --git a/.riot/requirements/106f38d.txt b/.riot/requirements/106f38d.txt deleted file mode 100644 index 35ad753ef8f..00000000000 --- a/.riot/requirements/106f38d.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.14 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/106f38d.in -# -attrs==25.3.0 -coverage[toml]==7.10.5 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.2 -pymongo==4.8.0 -pytest==8.4.1 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/1087ca6.txt b/.riot/requirements/1087ca6.txt deleted file mode 100644 index 875cc5be3a4..00000000000 --- a/.riot/requirements/1087ca6.txt +++ /dev/null @@ -1,26 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1087ca6.in -# -attrs==25.3.0 -coverage[toml]==7.8.2 -dnspython==2.7.0 -exceptiongroup==1.3.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.1 -pymongo==4.8.0 -pytest==8.4.0 -pytest-cov==6.1.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 -tomli==2.2.1 -typing-extensions==4.14.0 diff --git a/.riot/requirements/10a00e7.txt b/.riot/requirements/10a00e7.txt deleted file mode 100644 index ed2fd846015..00000000000 --- a/.riot/requirements/10a00e7.txt +++ /dev/null @@ -1,24 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/10a00e7.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -exceptiongroup==1.2.2 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.0.1 diff --git a/.riot/requirements/10b490c.txt b/.riot/requirements/10b490c.txt deleted file mode 100644 index 4126321ff11..00000000000 --- a/.riot/requirements/10b490c.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/10b490c.in -# -attrs==25.3.0 -coverage[toml]==7.8.2 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.1 -pymongo==4.8.0 -pytest==8.4.0 -pytest-cov==6.1.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/1424e42.txt b/.riot/requirements/1424e42.txt deleted file mode 100644 index f58bbb22bd6..00000000000 --- a/.riot/requirements/1424e42.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/1424e42.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/1468cf5.txt b/.riot/requirements/1468cf5.txt deleted file mode 100644 index 6b90ac2ac97..00000000000 --- a/.riot/requirements/1468cf5.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.14 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1468cf5.in -# -attrs==25.3.0 -coverage[toml]==7.10.5 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.2 -pymongo==4.8.0 -pytest==8.4.1 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/14e85f3.txt b/.riot/requirements/14e85f3.txt deleted file mode 100644 index 44ce4a54256..00000000000 --- a/.riot/requirements/14e85f3.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/14e85f3.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/164d658.txt b/.riot/requirements/164d658.txt deleted file mode 100644 index cd0bb3c4f4c..00000000000 --- a/.riot/requirements/164d658.txt +++ /dev/null @@ -1,27 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/164d658.in -# -attrs==23.1.0 -cassandra-driver==3.28.0 -click==8.1.7 -coverage[toml]==7.3.4 -exceptiongroup==1.2.0 -geomet==0.2.1.post1 -hypothesis==6.45.0 -importlib-metadata==7.0.0 -iniconfig==2.0.0 -mock==5.1.0 -opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.3 -pytest-cov==4.1.0 -pytest-mock==3.12.0 -pytest-randomly==3.15.0 -six==1.16.0 -sortedcontainers==2.4.0 -tomli==2.0.1 -zipp==3.17.0 diff --git a/.riot/requirements/168e13d.txt b/.riot/requirements/168e13d.txt deleted file mode 100644 index 5161e01c8a3..00000000000 --- a/.riot/requirements/168e13d.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.14 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/168e13d.in -# -attrs==25.3.0 -coverage[toml]==7.10.5 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.2 -pymongo==4.8.0 -pytest==8.4.1 -pytest-cov==6.2.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/170ff7e.txt b/.riot/requirements/170ff7e.txt deleted file mode 100644 index 64fffcfc4f2..00000000000 --- a/.riot/requirements/170ff7e.txt +++ /dev/null @@ -1,28 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate --resolver=backtracking .riot/requirements/170ff7e.in -# -attrs==25.3.0 -coverage[toml]==7.8.2 -dnspython==2.7.0 -exceptiongroup==1.3.0 -hypothesis==6.45.0 -importlib-metadata==8.7.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.1 -pymongo==4.8.0 -pytest==8.4.0 -pytest-cov==6.1.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 -tomli==2.2.1 -typing-extensions==4.14.0 -zipp==3.23.0 diff --git a/.riot/requirements/1c4e625.txt b/.riot/requirements/1c4e625.txt deleted file mode 100644 index 4ee880ebb56..00000000000 --- a/.riot/requirements/1c4e625.txt +++ /dev/null @@ -1,26 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate --resolver=backtracking .riot/requirements/1c4e625.in -# -attrs==25.3.0 -coverage[toml]==7.6.1 -exceptiongroup==1.3.0 -hypothesis==6.45.0 -importlib-metadata==8.5.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.23.1 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.5.0 -pymongo==3.13.0 -pytest==8.3.5 -pytest-cov==5.0.0 -pytest-mock==3.14.1 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.2.1 -typing-extensions==4.13.2 -zipp==3.20.2 diff --git a/.riot/requirements/1ce93b3.txt b/.riot/requirements/1ce93b3.txt deleted file mode 100644 index a0edba9ffd0..00000000000 --- a/.riot/requirements/1ce93b3.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1ce93b3.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/328b28c.txt b/.riot/requirements/328b28c.txt deleted file mode 100644 index 38eac9651b9..00000000000 --- a/.riot/requirements/328b28c.txt +++ /dev/null @@ -1,24 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/328b28c.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -exceptiongroup==1.2.2 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.0.1 diff --git a/.riot/requirements/3dd53da.txt b/.riot/requirements/3dd53da.txt deleted file mode 100644 index 088ac0ddd7e..00000000000 --- a/.riot/requirements/3dd53da.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/3dd53da.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/40a41fd.txt b/.riot/requirements/40a41fd.txt deleted file mode 100644 index 9f9034b3892..00000000000 --- a/.riot/requirements/40a41fd.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.13 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/40a41fd.in -# -attrs==25.3.0 -coverage[toml]==7.8.2 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.1 -pymongo==4.8.0 -pytest==8.4.0 -pytest-cov==6.1.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/a0b94b1.txt b/.riot/requirements/a0b94b1.txt deleted file mode 100644 index 71d76a09e22..00000000000 --- a/.riot/requirements/a0b94b1.txt +++ /dev/null @@ -1,23 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --allow-unsafe --no-annotate .riot/requirements/a0b94b1.in -# -attrs==25.3.0 -coverage[toml]==7.8.2 -dnspython==2.7.0 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -mongoengine==0.24.2 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.6.0 -pygments==2.19.1 -pymongo==4.8.0 -pytest==8.4.0 -pytest-cov==6.1.1 -pytest-mock==3.14.1 -pytest-randomly==3.16.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/ad40916.txt b/.riot/requirements/ad40916.txt deleted file mode 100644 index 853f497ee9e..00000000000 --- a/.riot/requirements/ad40916.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/ad40916.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/b089663.txt b/.riot/requirements/b089663.txt deleted file mode 100644 index 956c6d73e92..00000000000 --- a/.riot/requirements/b089663.txt +++ /dev/null @@ -1,26 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/b089663.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -exceptiongroup==1.2.2 -hypothesis==6.45.0 -importlib-metadata==8.5.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.0.1 -zipp==3.20.2 diff --git a/.riot/requirements/b344fed.txt b/.riot/requirements/b344fed.txt deleted file mode 100644 index 73e61eb69f9..00000000000 --- a/.riot/requirements/b344fed.txt +++ /dev/null @@ -1,22 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/b344fed.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -hypothesis==6.45.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 diff --git a/.riot/requirements/de53117.txt b/.riot/requirements/de53117.txt deleted file mode 100644 index 1dd3dcf18f2..00000000000 --- a/.riot/requirements/de53117.txt +++ /dev/null @@ -1,26 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/de53117.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -exceptiongroup==1.2.2 -hypothesis==6.45.0 -importlib-metadata==8.5.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.0.1 -zipp==3.20.2 diff --git a/.riot/requirements/f229429.txt b/.riot/requirements/f229429.txt deleted file mode 100644 index 4f0448ccdbb..00000000000 --- a/.riot/requirements/f229429.txt +++ /dev/null @@ -1,27 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/f229429.in -# -attrs==23.1.0 -cassandra-driver==3.24.0 -click==8.1.7 -coverage[toml]==7.3.4 -exceptiongroup==1.2.0 -geomet==0.2.1.post1 -hypothesis==6.45.0 -importlib-metadata==7.0.0 -iniconfig==2.0.0 -mock==5.1.0 -opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.3 -pytest-cov==4.1.0 -pytest-mock==3.12.0 -pytest-randomly==3.15.0 -six==1.16.0 -sortedcontainers==2.4.0 -tomli==2.0.1 -zipp==3.17.0 diff --git a/.riot/requirements/f9d0e8e.txt b/.riot/requirements/f9d0e8e.txt deleted file mode 100644 index 42bc8937d56..00000000000 --- a/.riot/requirements/f9d0e8e.txt +++ /dev/null @@ -1,26 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/f9d0e8e.in -# -attrs==24.2.0 -coverage[toml]==7.6.1 -dnspython==2.6.1 -exceptiongroup==1.2.2 -hypothesis==6.45.0 -importlib-metadata==8.5.0 -iniconfig==2.0.0 -mock==5.1.0 -mongoengine==0.29.1 -opentracing==2.4.0 -packaging==24.1 -pluggy==1.5.0 -pymongo==4.8.0 -pytest==8.3.3 -pytest-cov==5.0.0 -pytest-mock==3.14.0 -pytest-randomly==3.15.0 -sortedcontainers==2.4.0 -tomli==2.0.1 -zipp==3.20.2 diff --git a/ddtrace/_monkey.py b/ddtrace/_monkey.py index 599a4dae857..170c1870871 100644 --- a/ddtrace/_monkey.py +++ b/ddtrace/_monkey.py @@ -38,7 +38,6 @@ "boto": True, "botocore": True, "bottle": True, - "cassandra": True, "celery": True, "consul": True, "ddtrace_api": True, @@ -58,7 +57,6 @@ "kafka": True, "langgraph": True, "litellm": True, - "mongoengine": True, "mysql": True, "mysqldb": True, "pymysql": True, @@ -155,7 +153,6 @@ "psycopg2", ), "snowflake": ("snowflake.connector",), - "cassandra": ("cassandra.cluster",), "dogpile_cache": ("dogpile.cache",), "mysqldb": ("MySQLdb",), "futures": ("concurrent.futures.thread",), @@ -334,7 +331,7 @@ def patch_all(**patch_modules: bool) -> None: :param dict patch_modules: Override whether particular modules are patched or not. - >>> _patch_all(redis=False, cassandra=False) + >>> _patch_all(redis=False) """ deprecate( "patch_all is deprecated and will be removed in a future version of the tracer.", diff --git a/ddtrace/_trace/span.py b/ddtrace/_trace/span.py index 9e306f621bc..df5c36df611 100644 --- a/ddtrace/_trace/span.py +++ b/ddtrace/_trace/span.py @@ -52,10 +52,8 @@ from ddtrace.internal.constants import SPAN_API_DATADOG from ddtrace.internal.constants import SamplingMechanism from ddtrace.internal.logger import get_logger -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning from ddtrace.internal.utils.time import Time from ddtrace.settings._config import config -from ddtrace.vendor.debtcollector import deprecate from ddtrace.vendor.debtcollector import removals @@ -630,8 +628,6 @@ def record_exception( self, exception: BaseException, attributes: Optional[Dict[str, _AttributeValueType]] = None, - timestamp: Optional[int] = None, - escaped: bool = False, ) -> None: """ Records an exception as a span event. Multiple exceptions can be recorded on a span. @@ -643,23 +639,6 @@ def record_exception( :param timestamp: Deprecated. :param escaped: Deprecated. """ - if escaped: - deprecate( - prefix="The escaped argument is deprecated for record_exception", - message="""If an exception exits the scope of the span, it will automatically be - reported in the span tags.""", - category=DDTraceDeprecationWarning, - removal_version="4.0.0", - ) - if timestamp is not None: - deprecate( - prefix="The timestamp argument is deprecated for record_exception", - message="""The timestamp of the span event should correspond to the time when the - error is recorded which is set automatically.""", - category=DDTraceDeprecationWarning, - removal_version="4.0.0", - ) - tb = self._get_traceback(type(exception), exception, exception.__traceback__) attrs: Dict[str, _AttributeValueType] = { @@ -847,18 +826,6 @@ def __exit__( except Exception: log.exception("error closing trace") - def _pprint(self) -> str: - # Although Span._pprint has been internal to ddtrace since v1.0.0, it is still - # used to debug spans in the wild. Introducing a deprecation warning here to - # give users a chance to migrate to __repr__ before we remove it. - deprecate( - prefix="The _pprint method is deprecated for __repr__", - message="""Use __repr__ instead.""", - category=DDTraceDeprecationWarning, - removal_version="4.0.0", - ) - return self.__repr__() - def __repr__(self) -> str: """Return a detailed string representation of a span.""" return ( diff --git a/ddtrace/contrib/integration_registry/registry.yaml b/ddtrace/contrib/integration_registry/registry.yaml index 4a467241940..2adf38cf686 100644 --- a/ddtrace/contrib/integration_registry/registry.yaml +++ b/ddtrace/contrib/integration_registry/registry.yaml @@ -195,16 +195,6 @@ integrations: min: 0.12.25 max: 0.13.4 -- integration_name: cassandra - is_external_package: true - is_tested: true - dependency_names: - - cassandra-driver - tested_versions_by_dependency: - cassandra-driver: - min: 3.24.0 - max: 3.28.0 - - integration_name: celery is_external_package: true is_tested: true @@ -609,16 +599,6 @@ integrations: min: 1.0.2 max: 1.0.2 -- integration_name: mongoengine - is_external_package: true - is_tested: true - dependency_names: - - mongoengine - tested_versions_by_dependency: - mongoengine: - min: 0.23.1 - max: 0.29.1 - - integration_name: mysql is_external_package: true is_tested: true diff --git a/ddtrace/contrib/internal/cassandra/__init__.py b/ddtrace/contrib/internal/cassandra/__init__.py deleted file mode 100644 index d0de07f8f16..00000000000 --- a/ddtrace/contrib/internal/cassandra/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Instrument Cassandra to report Cassandra queries. - -``import ddtrace.auto`` will automatically patch your Cluster instance to make it work. -:: - - from ddtrace import patch - from ddtrace.trace import Pin - from cassandra.cluster import Cluster - - # If not patched yet, you can patch cassandra specifically - patch(cassandra=True) - - # This will report spans with the default instrumentation - cluster = Cluster(contact_points=["127.0.0.1"], port=9042) - session = cluster.connect("my_keyspace") - # Example of instrumented query - session.execute("select id from my_table limit 10;") - - # Use a pin to specify metadata related to this cluster - cluster = Cluster(contact_points=['10.1.1.3', '10.1.1.4', '10.1.1.5'], port=9042) - Pin.override(cluster, service='cassandra-backend') - session = cluster.connect("my_keyspace") - session.execute("select id from my_table limit 10;") -""" diff --git a/ddtrace/contrib/internal/cassandra/patch.py b/ddtrace/contrib/internal/cassandra/patch.py deleted file mode 100644 index bc82b8dbe0e..00000000000 --- a/ddtrace/contrib/internal/cassandra/patch.py +++ /dev/null @@ -1,9 +0,0 @@ -from typing import Dict - -from .session import get_version # noqa: F401 -from .session import patch # noqa: F401 -from .session import unpatch # noqa: F401 - - -def _supported_versions() -> Dict[str, str]: - return {"cassandra": ">=3.24.0"} diff --git a/ddtrace/contrib/internal/cassandra/session.py b/ddtrace/contrib/internal/cassandra/session.py deleted file mode 100644 index 92b0bf989bc..00000000000 --- a/ddtrace/contrib/internal/cassandra/session.py +++ /dev/null @@ -1,316 +0,0 @@ -""" -Trace queries along a session to a cassandra cluster -""" -import sys -from typing import Any -from typing import Dict -from typing import List -from typing import Optional - -from cassandra import __version__ - - -try: - import cassandra.cluster as cassandra_cluster -except AttributeError: - from cassandra import cluster as cassandra_cluster -from cassandra.query import BatchStatement -from cassandra.query import BoundStatement -from cassandra.query import PreparedStatement -from cassandra.query import SimpleStatement -import wrapt - -from ddtrace import config -from ddtrace._trace.pin import Pin -from ddtrace.constants import _SPAN_MEASURED_KEY -from ddtrace.constants import ERROR_MSG -from ddtrace.constants import ERROR_TYPE -from ddtrace.constants import SPAN_KIND -from ddtrace.ext import SpanKind -from ddtrace.ext import SpanTypes -from ddtrace.ext import cassandra as cassx -from ddtrace.ext import db -from ddtrace.ext import net -from ddtrace.internal.compat import maybe_stringify -from ddtrace.internal.constants import COMPONENT -from ddtrace.internal.logger import get_logger -from ddtrace.internal.schema import schematize_database_operation -from ddtrace.internal.schema import schematize_service_name -from ddtrace.internal.utils import get_argument_value -from ddtrace.internal.utils.formats import deep_getattr -from ddtrace.trace import Span - - -log = get_logger(__name__) - -RESOURCE_MAX_LENGTH = 5000 -SERVICE = schematize_service_name("cassandra") -CURRENT_SPAN = "_ddtrace_current_span" -PAGE_NUMBER = "_ddtrace_page_number" - - -# Original connect connect function -_connect = cassandra_cluster.Cluster.connect - - -def get_version(): - # type: () -> str - return __version__ - - -def patch(): - """patch will add tracing to the cassandra library.""" - cassandra_cluster.Cluster.connect = wrapt.FunctionWrapper(_connect, traced_connect) - Pin(service=SERVICE).onto(cassandra_cluster.Cluster) - cassandra_cluster._datadog_patch = True - - -def unpatch(): - cassandra_cluster.Cluster.connect = _connect - cassandra_cluster._datadog_patch = False - - -def traced_connect(func, instance, args, kwargs): - session = func(*args, **kwargs) - if not isinstance(session.execute, wrapt.FunctionWrapper): - # FIXME[matt] this should probably be private. - session.execute_async = wrapt.FunctionWrapper(session.execute_async, traced_execute_async) - return session - - -def _close_span_on_success(result, future): - span = getattr(future, CURRENT_SPAN, None) - if not span: - log.debug("traced_set_final_result was not able to get the current span from the ResponseFuture") - return - try: - span.set_tags(_extract_result_metas(cassandra_cluster.ResultSet(future, result))) - except Exception: - log.debug("an exception occurred while setting tags", exc_info=True) - finally: - span.finish() - delattr(future, CURRENT_SPAN) - - -def traced_set_final_result(func, instance, args, kwargs): - result = get_argument_value(args, kwargs, 0, "response") - _close_span_on_success(result, instance) - return func(*args, **kwargs) - - -def _close_span_on_error(exc, future): - span = getattr(future, CURRENT_SPAN, None) - if not span: - log.debug("traced_set_final_exception was not able to get the current span from the ResponseFuture") - return - try: - # handling the exception manually because we - # don't have an ongoing exception here - span.error = 1 - span._set_tag_str(ERROR_MSG, exc.args[0]) - span._set_tag_str(ERROR_TYPE, exc.__class__.__name__) - except Exception: - log.debug("traced_set_final_exception was not able to set the error, failed with error", exc_info=True) - finally: - span.finish() - delattr(future, CURRENT_SPAN) - - -def traced_set_final_exception(func, instance, args, kwargs): - exc = get_argument_value(args, kwargs, 0, "response") - _close_span_on_error(exc, instance) - return func(*args, **kwargs) - - -def traced_start_fetching_next_page(func, instance, args, kwargs): - has_more_pages = getattr(instance, "has_more_pages", True) - if not has_more_pages: - return func(*args, **kwargs) - session = getattr(instance, "session", None) - cluster = getattr(session, "cluster", None) - pin = Pin.get_from(cluster) - if not pin or not pin.enabled(): - return func(*args, **kwargs) - - # In case the current span is not finished we make sure to finish it - old_span = getattr(instance, CURRENT_SPAN, None) - if old_span: - log.debug("previous span was not finished before fetching next page") - old_span.finish() - - query = getattr(instance, "query", None) - - sanitized_query = _sanitize_query(query) if isinstance(query, BatchStatement) else None - statements_and_parameters = query._statements_and_parameters if isinstance(query, BatchStatement) else None - additional_tags = dict(**_extract_session_metas(session), **_extract_cluster_metas(cluster)) - span = _start_span_and_set_tags( - pin, _get_resource(query), additional_tags, sanitized_query, statements_and_parameters - ) - - page_number = getattr(instance, PAGE_NUMBER, 1) + 1 - setattr(instance, PAGE_NUMBER, page_number) - setattr(instance, CURRENT_SPAN, span) - try: - return func(*args, **kwargs) - except Exception: - with span: - span.set_exc_info(*sys.exc_info()) - raise - - -def traced_execute_async(func, instance, args, kwargs): - cluster = getattr(instance, "cluster", None) - pin = Pin.get_from(cluster) - if not pin or not pin.enabled(): - return func(*args, **kwargs) - - query = get_argument_value(args, kwargs, 0, "query") - - sanitized_query = _sanitize_query(query) if isinstance(query, BatchStatement) else None - statements_and_parameters = query._statements_and_parameters if isinstance(query, BatchStatement) else None - additional_tags = dict(**_extract_session_metas(instance), **_extract_cluster_metas(cluster)) - span = _start_span_and_set_tags( - pin, _get_resource(query), additional_tags, sanitized_query, statements_and_parameters - ) - - try: - result = func(*args, **kwargs) - setattr(result, CURRENT_SPAN, span) - setattr(result, PAGE_NUMBER, 1) - result._set_final_result = wrapt.FunctionWrapper(result._set_final_result, traced_set_final_result) - result._set_final_exception = wrapt.FunctionWrapper(result._set_final_exception, traced_set_final_exception) - result.start_fetching_next_page = wrapt.FunctionWrapper( - result.start_fetching_next_page, traced_start_fetching_next_page - ) - - # Since we cannot be sure that the previous methods were overwritten - # before the call ended, we add callbacks that will be run - # synchronously if the call already returned and we remove them right - # after. - result.add_callbacks( - _close_span_on_success, _close_span_on_error, callback_args=(result,), errback_args=(result,) - ) - result.clear_callbacks() - return result - except Exception: - with span: - span.set_exc_info(*sys.exc_info()) - raise - - -def _start_span_and_set_tags( - pin, - resource: str, - additional_tags: Dict, - query: Optional[str] = None, - statements_and_parameters: Optional[List] = None, -) -> Span: - span = pin.tracer.trace( - schematize_database_operation("cassandra.query", database_provider="cassandra"), - service=pin.service, - span_type=SpanTypes.CASSANDRA, - ) - span._set_tag_str(COMPONENT, config.cassandra.integration_name) - span._set_tag_str(db.SYSTEM, "cassandra") - span._set_tag_str(SPAN_KIND, SpanKind.CLIENT) - # PERF: avoid setting via Span.set_tag - span.set_metric(_SPAN_MEASURED_KEY, 1) - span.set_tags(additional_tags) - if query is not None: - span._set_tag_str("cassandra.query", query) - if statements_and_parameters is not None: - span.set_metric("cassandra.batch_size", len(statements_and_parameters)) - span.resource = resource[:RESOURCE_MAX_LENGTH] - return span - - -def _extract_session_metas(session): - metas = {} - - if getattr(session, "keyspace", None): - # FIXME the keyspace can be overridden explicitly in the query itself - # e.g. 'select * from trace.hash_to_resource' - metas[cassx.KEYSPACE] = session.keyspace.lower() - - return metas - - -def _extract_cluster_metas(cluster): - metas = {} - if deep_getattr(cluster, "metadata.cluster_name"): - metas[cassx.CLUSTER] = cluster.metadata.cluster_name - if getattr(cluster, "port", None): - metas[net.TARGET_PORT] = cluster.port - - return metas - - -def _extract_result_metas(result): - metas = {} - if result is None: - return metas - - future = getattr(result, "response_future", None) - - if future: - # get the host - host = maybe_stringify(getattr(future, "coordinator_host", None)) - if host: - host, _, port = host.partition(":") - metas[net.TARGET_HOST] = host - metas[net.SERVER_ADDRESS] = host - if port: - metas[net.TARGET_PORT] = int(port) - elif hasattr(future, "_current_host"): - address = deep_getattr(future, "_current_host.address") - if address: - metas[net.TARGET_HOST] = address - metas[net.SERVER_ADDRESS] = address - - query = getattr(future, "query", None) - if getattr(query, "consistency_level", None): - metas[cassx.CONSISTENCY_LEVEL] = query.consistency_level - if getattr(query, "keyspace", None): - metas[cassx.KEYSPACE] = query.keyspace.lower() - - page_number = getattr(future, PAGE_NUMBER, 1) - has_more_pages = future.has_more_pages - is_paginated = has_more_pages or page_number > 1 - metas[cassx.PAGINATED] = is_paginated - if is_paginated: - metas[cassx.PAGE_NUMBER] = page_number - - if hasattr(result, "current_rows"): - result_rows = result.current_rows or [] - metas[db.ROWCOUNT] = len(result_rows) - - return metas - - -def _get_resource(query: Any) -> str: - if isinstance(query, SimpleStatement) or isinstance(query, PreparedStatement): - return getattr(query, "query_string", query) - elif isinstance(query, BatchStatement): - return "BatchStatement" - elif isinstance(query, BoundStatement): - ps = getattr(query, "prepared_statement", None) - if ps: - return getattr(ps, "query_string", None) - elif isinstance(query, str): - return query - else: - return "unknown-query-type" - - -def _sanitize_query(query: BatchStatement) -> str: - """ - Each element in `_statements_and_parameters` is: - (is_prepared, statement, parameters) - ref:https://github.com/datastax/python-driver/blob/13d6d72be74f40fcef5ec0f2b3e98538b3b87459/cassandra/query.py#L844 - - For prepared statements, the `statement` value is just the query_id - which is not a statement and when trying to join with other strings - raises an error in python3 around joining bytes to unicode, so this - just filters out prepared statements from this tag value - """ - return "; ".join(q[1] for q in query._statements_and_parameters[:2] if not q[0]) diff --git a/ddtrace/contrib/internal/mongoengine/__init__.py b/ddtrace/contrib/internal/mongoengine/__init__.py deleted file mode 100644 index a72c861f4b7..00000000000 --- a/ddtrace/contrib/internal/mongoengine/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Instrument mongoengine to report MongoDB queries. - -``import ddtrace.auto`` will automatically patch your mongoengine connect method to make it work. -:: - - from ddtrace import patch - from ddtrace.trace import Pin - import mongoengine - - # If not patched yet, you can patch mongoengine specifically - patch(mongoengine=True) - - # At that point, mongoengine is instrumented with the default settings - mongoengine.connect('db', alias='default') - - # Use a pin to specify metadata related to this client - client = mongoengine.connect('db', alias='master') - Pin.override(client, service="mongo-master") -""" diff --git a/ddtrace/contrib/internal/mongoengine/patch.py b/ddtrace/contrib/internal/mongoengine/patch.py deleted file mode 100644 index 550d1e83199..00000000000 --- a/ddtrace/contrib/internal/mongoengine/patch.py +++ /dev/null @@ -1,38 +0,0 @@ -# TODO(mabdinur): Remove the pymongoengine integration, this integration does nothing special -# it just uses the pymongo integration and creates unnecessary pin objects -from typing import Dict - -import mongoengine - -from ..pymongo.patch import patch as patch_pymongo_module -from ..pymongo.patch import unpatch as unpatch_pymongo_module -from .trace import WrappedConnect - - -# Original connect function -_connect = mongoengine.connect - - -def get_version(): - # type: () -> str - return getattr(mongoengine, "__version__", "") - - -def _supported_versions() -> Dict[str, str]: - return {"mongoengine": ">=0.23"} - - -def patch(): - if getattr(mongoengine, "_datadog_patch", False): - return - mongoengine.connect = WrappedConnect(_connect) - mongoengine._datadog_patch = True - patch_pymongo_module() - - -def unpatch(): - if not getattr(mongoengine, "_datadog_patch", False): - return - mongoengine.connect = _connect - mongoengine._datadog_patch = False - unpatch_pymongo_module() diff --git a/ddtrace/contrib/internal/mongoengine/trace.py b/ddtrace/contrib/internal/mongoengine/trace.py deleted file mode 100644 index e3deee0e4a4..00000000000 --- a/ddtrace/contrib/internal/mongoengine/trace.py +++ /dev/null @@ -1,38 +0,0 @@ -# 3p -# project -import wrapt - -from ddtrace._trace.pin import Pin - -# keep the TracedMongoClient import to avoid breaking the public api -from ddtrace.contrib.internal.pymongo.client import TracedMongoClient # noqa: F401 -from ddtrace.ext import mongo as mongox -from ddtrace.internal.schema import schematize_service_name - - -# TODO(Benjamin): we should instrument register_connection instead, because more generic -# We should also extract the "alias" attribute and set it as a meta -_SERVICE = schematize_service_name(mongox.SERVICE) - - -# TODO(mabdinur): Remove this class when ``ddtrace.contrib.mongoengine.trace`` is removed -class WrappedConnect(wrapt.ObjectProxy): - """WrappedConnect wraps mongoengines 'connect' function to ensure - that all returned connections are wrapped for tracing. - """ - - def __init__(self, connect): - super(WrappedConnect, self).__init__(connect) - Pin(_SERVICE).onto(self) - - def __call__(self, *args, **kwargs): - client = self.__wrapped__(*args, **kwargs) - pin = Pin.get_from(self) - if pin: - tracer = pin.tracer - pp = Pin(service=pin.service) - if tracer is not None: - pp._tracer = tracer - pp.onto(client) - - return client diff --git a/ddtrace/ext/cassandra.py b/ddtrace/ext/cassandra.py deleted file mode 100644 index d510897d12d..00000000000 --- a/ddtrace/ext/cassandra.py +++ /dev/null @@ -1,6 +0,0 @@ -# tags -CLUSTER = "cassandra.cluster" -KEYSPACE = "cassandra.keyspace" -CONSISTENCY_LEVEL = "cassandra.consistency_level" -PAGINATED = "cassandra.paginated" -PAGE_NUMBER = "cassandra.page_number" diff --git a/ddtrace/opentracer/__init__.py b/ddtrace/opentracer/__init__.py deleted file mode 100644 index 815cdae0022..00000000000 --- a/ddtrace/opentracer/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -from ddtrace.vendor.debtcollector import deprecate - -from .helpers import set_global_tracer -from .tracer import Tracer - - -deprecate( - "The `ddtrace.opentracer` package is deprecated", - message="The ddtrace library no longer supports the OpenTracing API. " - "Use the OpenTelemetry API instead (`ddtrace.opentelemetry`).", - removal_version="4.0.0", -) - - -__all__ = [ - "Tracer", - "set_global_tracer", -] diff --git a/ddtrace/opentracer/helpers.py b/ddtrace/opentracer/helpers.py deleted file mode 100644 index e8e6c4896a4..00000000000 --- a/ddtrace/opentracer/helpers.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import TYPE_CHECKING - -import opentracing - -import ddtrace - - -if TYPE_CHECKING: # pragma: no cover - from ddtrace.opentracer import Tracer # noqa:F401 - - -""" -Helper routines for Datadog OpenTracing. -""" - - -def set_global_tracer(tracer): - # type: (Tracer) -> None - """Sets the global tracers to the given tracer.""" - - # overwrite the opentracer reference - opentracing.tracer = tracer - - # overwrite the Datadog tracer reference - ddtrace.tracer = tracer._dd_tracer diff --git a/ddtrace/opentracer/propagation/__init__.py b/ddtrace/opentracer/propagation/__init__.py deleted file mode 100644 index 04ddde7014d..00000000000 --- a/ddtrace/opentracer/propagation/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .http import HTTPPropagator - - -__all__ = [ - "HTTPPropagator", -] diff --git a/ddtrace/opentracer/propagation/binary.py b/ddtrace/opentracer/propagation/binary.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ddtrace/opentracer/propagation/http.py b/ddtrace/opentracer/propagation/http.py deleted file mode 100644 index 539f8dc2ebd..00000000000 --- a/ddtrace/opentracer/propagation/http.py +++ /dev/null @@ -1,74 +0,0 @@ -from typing import Dict # noqa:F401 - -from opentracing import InvalidCarrierException - -from ddtrace.propagation.http import HTTPPropagator as DDHTTPPropagator - -from ...internal.logger import get_logger -from ..span_context import SpanContext -from .propagator import Propagator - - -log = get_logger(__name__) - -_HTTP_BAGGAGE_PREFIX = "ot-baggage-" -_HTTP_BAGGAGE_PREFIX_LEN = len(_HTTP_BAGGAGE_PREFIX) - - -class HTTPPropagator(Propagator): - """OpenTracing compatible HTTP_HEADER and TEXT_MAP format propagator. - - `HTTPPropagator` provides compatibility by using existing OpenTracing - compatible methods from the ddtracer along with new logic supporting the - outstanding OpenTracing-defined functionality. - """ - - @staticmethod - def inject(span_context, carrier): - # type: (SpanContext, Dict[str, str]) -> None - """Inject a span context into a carrier. - - *span_context* is injected into the carrier by first using an - :class:`ddtrace.propagation.http.HTTPPropagator` to inject the ddtracer - specific fields. - - Then the baggage is injected into *carrier*. - - :param span_context: span context to inject. - - :param carrier: carrier to inject into. - """ - if not isinstance(carrier, dict): - raise InvalidCarrierException("propagator expects carrier to be a dict") - - DDHTTPPropagator.inject(span_context._dd_context, carrier) - - # Add the baggage - if span_context.baggage is not None: - for key in span_context.baggage: - carrier[_HTTP_BAGGAGE_PREFIX + key] = span_context.baggage[key] - - @staticmethod - def extract(carrier): - # type: (Dict[str, str]) -> SpanContext - """Extract a span context from a carrier. - - :class:`ddtrace.propagation.http.HTTPPropagator` is used to extract - ddtracer supported fields into a `ddtrace.Context` context which is - combined with new logic to extract the baggage which is returned in an - OpenTracing compatible span context. - - :param carrier: carrier to extract from. - - :return: extracted span context. - """ - if not isinstance(carrier, dict): - raise InvalidCarrierException("propagator expects carrier to be a dict") - - ddspan_ctx = DDHTTPPropagator.extract(carrier) - baggage = {} - for key in carrier: - if key.startswith(_HTTP_BAGGAGE_PREFIX): - baggage[key[_HTTP_BAGGAGE_PREFIX_LEN:]] = carrier[key] - - return SpanContext(ddcontext=ddspan_ctx, baggage=baggage) diff --git a/ddtrace/opentracer/propagation/propagator.py b/ddtrace/opentracer/propagation/propagator.py deleted file mode 100644 index 77eadf3912b..00000000000 --- a/ddtrace/opentracer/propagation/propagator.py +++ /dev/null @@ -1,13 +0,0 @@ -import abc - - -class Propagator(metaclass=abc.ABCMeta): - @staticmethod - @abc.abstractmethod - def inject(span_context, carrier): - pass - - @staticmethod - @abc.abstractmethod - def extract(carrier): - pass diff --git a/ddtrace/opentracer/propagation/text.py b/ddtrace/opentracer/propagation/text.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ddtrace/opentracer/settings.py b/ddtrace/opentracer/settings.py deleted file mode 100644 index 944df88233b..00000000000 --- a/ddtrace/opentracer/settings.py +++ /dev/null @@ -1,41 +0,0 @@ -from collections import namedtuple -from typing import Any # noqa:F401 -from typing import Dict # noqa:F401 -from typing import List # noqa:F401 - - -# Keys used for the configuration dict -ConfigKeyNames = namedtuple( - "ConfigKeyNames", - [ - "AGENT_HOSTNAME", - "AGENT_HTTPS", - "AGENT_PORT", - "DEBUG", - "ENABLED", - "GLOBAL_TAGS", - "SAMPLER", - "PRIORITY_SAMPLING", - "UDS_PATH", - "SETTINGS", - ], -) - -ConfigKeys = ConfigKeyNames( - AGENT_HOSTNAME="agent_hostname", - AGENT_HTTPS="agent_https", - AGENT_PORT="agent_port", - DEBUG="debug", - ENABLED="enabled", - GLOBAL_TAGS="global_tags", - SAMPLER="sampler", - PRIORITY_SAMPLING="priority_sampling", - UDS_PATH="uds_path", - SETTINGS="settings", -) - - -def config_invalid_keys(config): - # type: (Dict[str, Any]) -> List[str] - """Returns a list of keys that exist in *config* and not in KEYS.""" - return [key for key in config.keys() if key not in ConfigKeys] diff --git a/ddtrace/opentracer/span.py b/ddtrace/opentracer/span.py deleted file mode 100644 index 3aea2eda580..00000000000 --- a/ddtrace/opentracer/span.py +++ /dev/null @@ -1,197 +0,0 @@ -import threading -from typing import TYPE_CHECKING # noqa:F401 -from typing import Any # noqa:F401 -from typing import Dict # noqa:F401 -from typing import Optional # noqa:F401 -from typing import Text # noqa:F401 -from typing import Union # noqa:F401 - -from opentracing import Span as OpenTracingSpan -from opentracing.ext import tags as OTTags - -from ddtrace.constants import ERROR_MSG -from ddtrace.constants import ERROR_STACK -from ddtrace.constants import ERROR_TYPE -from ddtrace.internal.compat import NumericType # noqa:F401 -from ddtrace.internal.constants import SPAN_API_OPENTRACING -from ddtrace.trace import Context as DatadogContext # noqa:F401 -from ddtrace.trace import Span as DatadogSpan - -from .span_context import SpanContext -from .tags import Tags - - -if TYPE_CHECKING: # pragma: no cover - from ddtrace.trace import Tracer # noqa:F401 - - -_TagNameType = Union[Text, bytes] - - -class Span(OpenTracingSpan): - """Datadog implementation of :class:`opentracing.Span`""" - - def __init__(self, tracer, context, operation_name): - # type: (Tracer, Optional[SpanContext], str) -> None - if context is not None: - context = SpanContext(ddcontext=context._dd_context, baggage=context.baggage) - else: - context = SpanContext() - - super(Span, self).__init__(tracer, context) - - self.finished = False - self._lock = threading.Lock() - # use a datadog span - self._dd_span = DatadogSpan(operation_name, context=context._dd_context, span_api=SPAN_API_OPENTRACING) - - def finish(self, finish_time=None): - # type: (Optional[float]) -> None - """Finish the span. - - This calls finish on the ddspan. - - :param finish_time: specify a custom finish time with a unix timestamp - per time.time() - :type timestamp: float - """ - if self.finished: - return - - # finish the datadog span - self._dd_span.finish(finish_time) - self.finished = True - - def set_baggage_item(self, key, value): - # type: (str, Any) -> Span - """Sets a baggage item in the span context of this span. - - Baggage is used to propagate state between spans. - - :param key: baggage item key - :type key: str - - :param value: baggage item value - :type value: a type that can be str'd - - :rtype: Span - :return: itself for chaining calls - """ - new_ctx = self.context.with_baggage_item(key, value) - with self._lock: - self._context = new_ctx - return self - - def get_baggage_item(self, key): - # type: (str) -> Optional[str] - """Gets a baggage item from the span context of this span. - - :param key: baggage item key - :type key: str - - :rtype: str - :return: the baggage value for the given key or ``None``. - """ - return self.context.get_baggage_item(key) - - def set_operation_name(self, operation_name): - # type: (str) -> Span - """Set the operation name.""" - self._dd_span.name = operation_name - return self - - def log_kv(self, key_values, timestamp=None): - # type: (Dict[_TagNameType, Any], Optional[float]) -> Span - """Add a log record to this span. - - Passes on relevant opentracing key values onto the datadog span. - - :param key_values: a dict of string keys and values of any type - :type key_values: dict - - :param timestamp: a unix timestamp per time.time() - :type timestamp: float - - :return: the span itself, for call chaining - :rtype: Span - """ - - # match opentracing defined keys to datadog functionality - # opentracing/specification/blob/1be630515dafd4d2a468d083300900f89f28e24d/semantic_conventions.md#log-fields-table # noqa: E501 - for key, val in key_values.items(): - if key == "event" and val == "error": - # TODO: not sure if it's actually necessary to set the error manually - self._dd_span.error = 1 - self.set_tag("error", 1) - elif key == "error" or key == "error.object": - self.set_tag(ERROR_TYPE, val) - elif key == "message": - self.set_tag(ERROR_MSG, val) - elif key == "stack": - self.set_tag(ERROR_STACK, val) - else: - pass - - return self - - def set_tag(self, key, value): - # type: (_TagNameType, Any) -> Span - """Set a tag on the span. - - This sets the tag on the underlying datadog span. - """ - if key == Tags.SPAN_TYPE: - self._dd_span.span_type = value - elif key == Tags.SERVICE_NAME: - self._dd_span.service = value - elif key == Tags.RESOURCE_NAME or key == OTTags.DATABASE_STATEMENT: - self._dd_span.resource = value - elif key == OTTags.PEER_HOSTNAME: - self._dd_span._set_tag_str(Tags.TARGET_HOST, value) - elif key == OTTags.PEER_PORT: - self._dd_span.set_tag(Tags.TARGET_PORT, value) - elif key == Tags.SAMPLING_PRIORITY: - self._dd_span.context.sampling_priority = value - else: - self._dd_span.set_tag(key, value) - return self - - def _get_tag(self, key): - # type: (_TagNameType) -> Optional[Text] - """Gets a tag from the span. - - This method retrieves the tag from the underlying datadog span. - """ - return self._dd_span.get_tag(key) - - def _get_metric(self, key): - # type: (_TagNameType) -> Optional[NumericType] - """Gets a metric from the span. - - This method retrieves the metric from the underlying datadog span. - """ - return self._dd_span.get_metric(key) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - if exc_type: - self._dd_span.set_exc_info(exc_type, exc_val, exc_tb) - - # note: self.finish() AND _dd_span.__exit__ will call _span.finish() but - # it is idempotent - self._dd_span.__exit__(exc_type, exc_val, exc_tb) - self.finish() - - def _associate_dd_span(self, ddspan): - # type: (DatadogSpan) -> None - """Associates a DD span with this span.""" - # get the datadog span context - self._dd_span = ddspan - self.context._dd_context = ddspan.context - - @property - def _dd_context(self): - # type: () -> DatadogContext - return self._dd_span.context diff --git a/ddtrace/opentracer/span_context.py b/ddtrace/opentracer/span_context.py deleted file mode 100644 index 171142d18a8..00000000000 --- a/ddtrace/opentracer/span_context.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import Any # noqa:F401 -from typing import Dict # noqa:F401 -from typing import Optional # noqa:F401 - -from opentracing import SpanContext as OpenTracingSpanContext - -from ddtrace.internal.compat import NumericType # noqa:F401 -from ddtrace.trace import Context as DatadogContext - - -class SpanContext(OpenTracingSpanContext): - """Implementation of the OpenTracing span context.""" - - def __init__( - self, - trace_id=None, # type: Optional[int] - span_id=None, # type: Optional[int] - sampling_priority=None, # type: Optional[NumericType] - baggage=None, # type: Optional[Dict[str, Any]] - ddcontext=None, # type: Optional[DatadogContext] - ): - # type: (...) -> None - # create a new dict for the baggage if it is not provided - # NOTE: it would be preferable to use opentracing.SpanContext.EMPTY_BAGGAGE - # but it is mutable. - # see: opentracing-python/blob/8775c7bfc57fd66e1c8bcf9a54d3e434d37544f9/opentracing/span.py#L30 - baggage = baggage or {} - - if ddcontext is not None: - self._dd_context = ddcontext - else: - self._dd_context = DatadogContext( - trace_id=trace_id, - span_id=span_id, - sampling_priority=sampling_priority, - ) - - self._baggage = dict(baggage) - - @property - def baggage(self): - # type: () -> Dict[str, Any] - return self._baggage - - def set_baggage_item(self, key, value): - # type: (str, Any) -> None - """Sets a baggage item in this span context. - - Note that this operation mutates the baggage of this span context - """ - self.baggage[key] = value - - def with_baggage_item(self, key, value): - # type: (str, Any) -> SpanContext - """Returns a copy of this span with a new baggage item. - - Useful for instantiating new child span contexts. - """ - baggage = dict(self._baggage) - baggage[key] = value - return SpanContext(ddcontext=self._dd_context, baggage=baggage) - - def get_baggage_item(self, key): - # type: (str) -> Optional[Any] - """Gets a baggage item in this span context.""" - return self.baggage.get(key, None) diff --git a/ddtrace/opentracer/tags.py b/ddtrace/opentracer/tags.py deleted file mode 100644 index ebc2d86d146..00000000000 --- a/ddtrace/opentracer/tags.py +++ /dev/null @@ -1,23 +0,0 @@ -from collections import namedtuple - - -TagNames = namedtuple( - "TagNames", - [ - "RESOURCE_NAME", - "SAMPLING_PRIORITY", - "SERVICE_NAME", - "SPAN_TYPE", - "TARGET_HOST", - "TARGET_PORT", - ], -) - -Tags = TagNames( - RESOURCE_NAME="resource.name", - SAMPLING_PRIORITY="sampling.priority", - SERVICE_NAME="service.name", - TARGET_HOST="out.host", - TARGET_PORT="network.destination.port", - SPAN_TYPE="span.type", -) diff --git a/ddtrace/opentracer/tracer.py b/ddtrace/opentracer/tracer.py deleted file mode 100644 index a783d3263dc..00000000000 --- a/ddtrace/opentracer/tracer.py +++ /dev/null @@ -1,399 +0,0 @@ -from typing import Any # noqa:F401 -from typing import Dict # noqa:F401 -from typing import List # noqa:F401 -from typing import Optional # noqa:F401 -from typing import Union # noqa:F401 -from urllib.parse import urlparse - -import opentracing -from opentracing import Format -from opentracing import Scope # noqa:F401 -from opentracing import ScopeManager # noqa:F401 -from opentracing.scope_managers import ThreadLocalScopeManager - -import ddtrace -from ddtrace import config as ddconfig -from ddtrace.internal.constants import SPAN_API_OPENTRACING -from ddtrace.internal.utils.config import get_application_name -from ddtrace.internal.writer import AgentWriterInterface -from ddtrace.settings.exceptions import ConfigException -from ddtrace.trace import Context as DatadogContext # noqa:F401 -from ddtrace.trace import Span as DatadogSpan -from ddtrace.trace import Tracer as DatadogTracer - -from ..internal.logger import get_logger -from .propagation import HTTPPropagator -from .settings import ConfigKeys as keys -from .settings import config_invalid_keys -from .span import Span -from .span_context import SpanContext -from .utils import get_context_provider_for_scope_manager - - -log = get_logger(__name__) - -DEFAULT_CONFIG: Dict[str, Optional[Any]] = { - keys.AGENT_HOSTNAME: None, - keys.AGENT_HTTPS: None, - keys.AGENT_PORT: None, - keys.DEBUG: False, - keys.ENABLED: None, - keys.GLOBAL_TAGS: {}, - keys.SAMPLER: None, - # Not used, priority sampling can not be disabled in +v3.0 - keys.PRIORITY_SAMPLING: None, - keys.UDS_PATH: None, - keys.SETTINGS: { - "FILTERS": [], - }, -} - - -class Tracer(opentracing.Tracer): - """A wrapper providing an OpenTracing API for the Datadog tracer.""" - - def __init__( - self, - service_name: Optional[str] = None, - config: Optional[Dict[str, Any]] = None, - scope_manager: Optional[ScopeManager] = None, - _dd_tracer: Optional[DatadogTracer] = None, - ) -> None: - """Initialize a new Datadog opentracer. - - :param service_name: (optional) the name of the service that this - tracer will be used with. Note if not provided, a service name will - try to be determined based off of ``sys.argv``. If this fails a - :class:`ddtrace.settings.ConfigException` will be raised. - :param config: (optional) a configuration object to specify additional - options. See the documentation for further information. - :param scope_manager: (optional) the scope manager for this tracer to - use. The available managers are listed in the Python OpenTracing repo - here: https://github.com/opentracing/opentracing-python#scope-managers. - If ``None`` is provided, defaults to - :class:`opentracing.scope_managers.ThreadLocalScopeManager`. - """ - # Merge the given config with the default into a new dict - self._config = DEFAULT_CONFIG.copy() - if config is not None: - self._config.update(config) - # Pull out commonly used properties for performance - self._service_name = service_name or get_application_name() - self._debug = self._config.get(keys.DEBUG) - - if self._debug and ddconfig._raise: - # Ensure there are no typos in any of the keys - invalid_keys = config_invalid_keys(self._config) - if invalid_keys: - str_invalid_keys = ",".join(invalid_keys) - raise ConfigException("invalid key(s) given ({})".format(str_invalid_keys)) - - if not self._service_name and ddconfig._raise: - raise ConfigException( - """ Cannot detect the \'service_name\'. - Please set the \'service_name=\' - keyword argument. - """ - ) - - self._scope_manager = scope_manager or ThreadLocalScopeManager() - self._dd_tracer = _dd_tracer or ddtrace.tracer - self._dd_tracer.context_provider = get_context_provider_for_scope_manager(self._scope_manager) - - self._dd_tracer.set_tags(self._config.get(keys.GLOBAL_TAGS)) # type: ignore[arg-type] - trace_processors = None - if isinstance(self._config.get(keys.SETTINGS), dict) and self._config[keys.SETTINGS].get("FILTERS"): # type: ignore[union-attr] - trace_processors = self._config[keys.SETTINGS]["FILTERS"] # type: ignore[index] - self._dd_tracer._span_aggregator.user_processors = trace_processors - - if self._config[keys.ENABLED]: - self._dd_tracer.enabled = self._config[keys.ENABLED] - - if ( - self._config[keys.AGENT_HOSTNAME] - or self._config[keys.AGENT_HTTPS] - or self._config[keys.AGENT_PORT] - or self._config[keys.UDS_PATH] - ): - scheme = "https" if self._config[keys.AGENT_HTTPS] else "http" - hostname = self._config[keys.AGENT_HOSTNAME] - port = self._config[keys.AGENT_PORT] - if self._dd_tracer._agent_url: - curr_agent_url = urlparse(self._dd_tracer._agent_url) - scheme = "https" if self._config[keys.AGENT_HTTPS] else curr_agent_url.scheme - hostname = hostname or curr_agent_url.hostname - port = port or curr_agent_url.port - uds_path = self._config[keys.UDS_PATH] - - if uds_path: - new_url = f"unix://{uds_path}" - else: - new_url = f"{scheme}://{hostname}:{port}" - if isinstance(self._dd_tracer._span_aggregator.writer, AgentWriterInterface): - self._dd_tracer._span_aggregator.writer.intake_url = new_url - self._dd_tracer._recreate() - - if self._config[keys.SAMPLER]: - self._dd_tracer._sampler = self._config[keys.SAMPLER] - - self._propagators = { - Format.HTTP_HEADERS: HTTPPropagator, - Format.TEXT_MAP: HTTPPropagator, - } - - @property - def scope_manager(self): - # type: () -> ScopeManager - """Returns the scope manager being used by this tracer.""" - return self._scope_manager - - def start_active_span( - self, - operation_name, # type: str - child_of=None, # type: Optional[Union[Span, SpanContext]] - references=None, # type: Optional[List[Any]] - tags=None, # type: Optional[Dict[str, str]] - start_time=None, # type: Optional[int] - ignore_active_span=False, # type: bool - finish_on_close=True, # type: bool - ): - # type: (...) -> Scope - """Returns a newly started and activated `Scope`. - The returned `Scope` supports with-statement contexts. For example:: - - with tracer.start_active_span('...') as scope: - scope.span.set_tag('http.method', 'GET') - do_some_work() - # Span.finish() is called as part of Scope deactivation through - # the with statement. - - It's also possible to not finish the `Span` when the `Scope` context - expires:: - - with tracer.start_active_span('...', - finish_on_close=False) as scope: - scope.span.set_tag('http.method', 'GET') - do_some_work() - # Span.finish() is not called as part of Scope deactivation as - # `finish_on_close` is `False`. - - :param operation_name: name of the operation represented by the new - span from the perspective of the current service. - :param child_of: (optional) a Span or SpanContext instance representing - the parent in a REFERENCE_CHILD_OF Reference. If specified, the - `references` parameter must be omitted. - :param references: (optional) a list of Reference objects that identify - one or more parent SpanContexts. (See the Reference documentation - for detail). - :param tags: an optional dictionary of Span Tags. The caller gives up - ownership of that dictionary, because the Tracer may use it as-is - to avoid extra data copying. - :param start_time: an explicit Span start time as a unix timestamp per - time.time(). - :param ignore_active_span: (optional) an explicit flag that ignores - the current active `Scope` and creates a root `Span`. - :param finish_on_close: whether span should automatically be finished - when `Scope.close()` is called. - :return: a `Scope`, already registered via the `ScopeManager`. - """ - otspan = 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, - ) - - # activate this new span - scope = self._scope_manager.activate(otspan, finish_on_close) - self._dd_tracer.context_provider.activate(otspan._dd_span) - return scope - - def start_span( - self, - operation_name: Optional[str] = None, - child_of: Optional[Union[Span, SpanContext]] = None, - references: Optional[List[Any]] = None, - tags: Optional[Dict[str, str]] = None, - start_time: Optional[int] = None, - ignore_active_span: bool = False, - ) -> Span: - """Starts and returns a new Span representing a unit of work. - - Starting a root Span (a Span with no causal references):: - - tracer.start_span('...') - - Starting a child Span (see also start_child_span()):: - - tracer.start_span( - '...', - child_of=parent_span) - - Starting a child Span in a more verbose way:: - - tracer.start_span( - '...', - references=[opentracing.child_of(parent_span)]) - - Note: the precedence when defining a relationship is the following, from highest to lowest: - 1. *child_of* - 2. *references* - 3. `scope_manager.active` (unless *ignore_active_span* is True) - 4. None - - Currently Datadog only supports `child_of` references. - - :param operation_name: name of the operation represented by the new - span from the perspective of the current service. - :param child_of: (optional) a Span or SpanContext instance representing - the parent in a REFERENCE_CHILD_OF Reference. If specified, the - `references` parameter must be omitted. - :param references: (optional) a list of Reference objects that identify - one or more parent SpanContexts. (See the Reference documentation - for detail) - :param tags: an optional dictionary of Span Tags. The caller gives up - ownership of that dictionary, because the Tracer may use it as-is - to avoid extra data copying. - :param start_time: an explicit Span start time as a unix timestamp per - time.time() - :param ignore_active_span: an explicit flag that ignores the current - active `Scope` and creates a root `Span`. - :return: an already-started Span instance. - """ - ot_parent = None # 'ot_parent' is more readable than 'child_of' - ot_parent_context = None # the parent span's context - # dd_parent: the child_of to pass to the ddtracer - dd_parent = None # type: Optional[Union[DatadogSpan, DatadogContext]] - - if child_of is not None: - ot_parent = child_of # 'ot_parent' is more readable than 'child_of' - elif references and isinstance(references, list): - # we currently only support child_of relations to one span - ot_parent = references[0].referenced_context - - # - whenever child_of is not None ddspans with parent-child - # relationships will share a ddcontext which maintains a hierarchy of - # ddspans for the execution flow - # - when child_of is a ddspan then the ddtracer uses this ddspan to - # create the child ddspan - # - when child_of is a ddcontext then the ddtracer uses the ddcontext to - # get_current_span() for the parent - if ot_parent is None and not ignore_active_span: - # attempt to get the parent span from the scope manager - scope = self._scope_manager.active - parent_span = getattr(scope, "span", None) - ot_parent_context = getattr(parent_span, "context", None) - - # Compare the active ot and dd spans. Using the one which - # was created later as the parent. - active_dd_parent = self._dd_tracer.context_provider.active() - if parent_span and isinstance(active_dd_parent, DatadogSpan): - dd_parent_span = parent_span._dd_span - if active_dd_parent.start_ns >= dd_parent_span.start_ns: - dd_parent = active_dd_parent - else: - dd_parent = dd_parent_span - else: - dd_parent = active_dd_parent - elif ot_parent is not None and isinstance(ot_parent, Span): - # a span is given to use as a parent - ot_parent_context = ot_parent.context - dd_parent = ot_parent._dd_span - elif ot_parent is not None and isinstance(ot_parent, SpanContext): - # a span context is given to use to find the parent ddspan - dd_parent = ot_parent._dd_context - elif ot_parent is None: - # user wants to create a new parent span we don't have to do - # anything - pass - elif ddconfig._raise: - raise TypeError("invalid span configuration given") - - # create a new otspan and ddspan using the ddtracer and associate it - # with the new otspan - ddspan = self._dd_tracer.start_span( - name=operation_name, # type: ignore[arg-type] - child_of=dd_parent, - service=self._service_name, - activate=False, - span_api=SPAN_API_OPENTRACING, - ) - - # set the start time if one is specified - ddspan.start = start_time or ddspan.start - - otspan = Span(self, ot_parent_context, operation_name) # type: ignore[arg-type] - # sync up the OT span with the DD span - otspan._associate_dd_span(ddspan) - - if tags is not None: - for k in tags: - # Make sure we set the tags on the otspan to ensure that the special compatibility tags - # are handled correctly (resource name, span type, sampling priority, etc). - otspan.set_tag(k, tags[k]) - - return otspan - - @property - def active_span(self): - # type: () -> Optional[Span] - """Retrieves the active span from the opentracing scope manager - - Falls back to using the datadog active span if one is not found. This - allows opentracing users to use datadog instrumentation. - """ - scope = self._scope_manager.active - if scope: - return scope.span - else: - dd_span = self._dd_tracer.current_span() - ot_span = None # type: Optional[Span] - if dd_span: - ot_span = Span(self, None, dd_span.name) - ot_span._associate_dd_span(dd_span) - return ot_span - - def inject(self, span_context, format, carrier): # noqa: A002 - # type: (SpanContext, str, Dict[str, str]) -> None - """Injects a span context into a carrier. - - :param span_context: span context to inject. - :param format: format to encode the span context with. - :param carrier: the carrier of the encoded span context. - """ - propagator = self._propagators.get(format, None) - - if propagator is None: - raise opentracing.UnsupportedFormatException - - propagator.inject(span_context, carrier) - - def extract(self, format, carrier): # noqa: A002 - # type: (str, Dict[str, str]) -> SpanContext - """Extracts a span context from a carrier. - - :param format: format that the carrier is encoded with. - :param carrier: the carrier to extract from. - """ - propagator = self._propagators.get(format, None) - - if propagator is None: - raise opentracing.UnsupportedFormatException - - # we have to manually activate the returned context from a distributed - # trace - ot_span_ctx = propagator.extract(carrier) - dd_span_ctx = ot_span_ctx._dd_context - self._dd_tracer.context_provider.activate(dd_span_ctx) - return ot_span_ctx - - def get_log_correlation_context(self): - # type: () -> Dict[str, str] - """Retrieves the data used to correlate a log with the current active trace. - Generates a dictionary for custom logging instrumentation including the trace id and - span id of the current active span, as well as the configured service, version, and environment names. - If there is no active span, a dictionary with an empty string for each value will be returned. - """ - return self._dd_tracer.get_log_correlation_context() diff --git a/ddtrace/opentracer/utils.py b/ddtrace/opentracer/utils.py deleted file mode 100644 index 886e998d8a3..00000000000 --- a/ddtrace/opentracer/utils.py +++ /dev/null @@ -1,43 +0,0 @@ -from opentracing import ScopeManager # noqa:F401 - -from ddtrace._trace.provider import BaseContextProvider -from ddtrace._trace.provider import DefaultContextProvider - - -# DEV: If `asyncio` or `gevent` are unavailable we do not throw an error, -# `context_provider` will just not be set and we'll get an `AttributeError` instead - - -def get_context_provider_for_scope_manager(scope_manager: ScopeManager) -> BaseContextProvider: - """Returns the context_provider to use with a given scope_manager.""" - - dd_context_provider = DefaultContextProvider() - _patch_scope_manager(scope_manager, dd_context_provider) - - return dd_context_provider - - -def _patch_scope_manager(scope_manager: ScopeManager, context_provider: BaseContextProvider) -> None: - """ - Patches a scope manager so that any time a span is activated - it'll also activate the underlying ddcontext with the underlying - datadog context provider. - - This allows opentracing users to rely on ddtrace.contrib patches and - have them parent correctly. - - :param scope_manager: Something that implements `opentracing.ScopeManager` - :param context_provider: Something that implements `datadog.provider.BaseContextProvider` - """ - if getattr(scope_manager, "_datadog_patch", False): - return - scope_manager._datadog_patch = True - - old_method = scope_manager.activate - - def _patched_activate(*args, **kwargs): - otspan = kwargs.get("span", args[0]) - context_provider.activate(otspan._dd_context) - return old_method(*args, **kwargs) - - scope_manager.activate = _patched_activate diff --git a/ddtrace/settings/_config.py b/ddtrace/settings/_config.py index 96c66bb5fce..41175d7a56f 100644 --- a/ddtrace/settings/_config.py +++ b/ddtrace/settings/_config.py @@ -158,7 +158,6 @@ "aiopg", "dogpile_cache", "pylibmc", - "mongoengine", "httpx", "httplib", "rq", @@ -178,7 +177,6 @@ "crewai", "pydantic_ai", "logging", - "cassandra", "boto", "mariadb", "aiohttp", diff --git a/docs/contributing-integrations.rst b/docs/contributing-integrations.rst index 8db0e205a2f..0ec2289013d 100644 --- a/docs/contributing-integrations.rst +++ b/docs/contributing-integrations.rst @@ -204,7 +204,6 @@ are not yet any expected spans stored for it, so we need to create some. mongo: - ddtrace/contrib/internal/pymongo/* - - ddtrace/contrib/internal/mongoengine/* - ddtrace/ext/mongo.py 15. Add a `suite` for your integration in `tests/contrib/suitespec.yml`. This defines test configuration diff --git a/docs/index.rst b/docs/index.rst index caf65d873e2..6b3d6ffa67c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -72,8 +72,6 @@ contacting support. +--------------------------------------------------+------------+----------+------+ | :ref:`bottle` | >= 0.12 | No | | +--------------------------------------------------+------------+----------+------+ -| :ref:`cassandra` | >= 3.24 | Yes | | -+--------------------------------------------------+------------+----------+------+ | :ref:`celery` | >= 4.4 | Yes | | +--------------------------------------------------+------------+----------+------+ | :ref:`cherrypy` | >= 17.0 | No | | @@ -154,8 +152,6 @@ contacting support. +--------------------------------------------------+------------+----------+------+ | :ref:`molten` | >= 1.0 | Yes | | +--------------------------------------------------+------------+----------+------+ -| :ref:`mongoengine` | >= 0.23 | Yes | | -+--------------------------------------------------+------------+----------+------+ | :ref:`mysql-connector` | >= 8.0.5 | Yes | | +--------------------------------------------------+------------+----------+------+ | :ref:`mysqldb` | \* | Yes | | diff --git a/docs/integrations.rst b/docs/integrations.rst index c33138a508e..b01829193c3 100644 --- a/docs/integrations.rst +++ b/docs/integrations.rst @@ -110,13 +110,6 @@ Bottle .. automodule:: ddtrace.contrib.bottle -.. _cassandra: - -Cassandra -^^^^^^^^^ -.. automodule:: ddtrace.contrib.internal.cassandra - - .. _celery: Celery @@ -375,13 +368,6 @@ Molten .. automodule:: ddtrace.contrib.internal.molten -.. _mongoengine: - -Mongoengine -^^^^^^^^^^^ -.. automodule:: ddtrace.contrib.internal.mongoengine - - .. _mysql-connector: mysql-connector diff --git a/releasenotes/notes/cassandra-d3c8aaf478bddc56.yaml b/releasenotes/notes/cassandra-d3c8aaf478bddc56.yaml new file mode 100644 index 00000000000..07df72ad56a --- /dev/null +++ b/releasenotes/notes/cassandra-d3c8aaf478bddc56.yaml @@ -0,0 +1,5 @@ +--- +other: + - | + cassandra: The Cassandra integration is removed because it is only compatible with Python 3.8, + which is a year past its end-of-life. diff --git a/releasenotes/notes/opentracer-remove-b1883d26ea035c50.yaml b/releasenotes/notes/opentracer-remove-b1883d26ea035c50.yaml new file mode 100644 index 00000000000..6d248930d9c --- /dev/null +++ b/releasenotes/notes/opentracer-remove-b1883d26ea035c50.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + opentracer: This change removes the deprecated ``opentracer`` package diff --git a/releasenotes/notes/remove-pymongo-engine-0584c2055377f718.yaml b/releasenotes/notes/remove-pymongo-engine-0584c2055377f718.yaml new file mode 100644 index 00000000000..772aade8185 --- /dev/null +++ b/releasenotes/notes/remove-pymongo-engine-0584c2055377f718.yaml @@ -0,0 +1,5 @@ +--- +other: + - | + mongoengine: Drops support for the ``ddtrace.Pin`` object with mongoengine. With this change, the ddtrace library no longer directly supports mongoengine. + Mongoengine will be supported through the ``pymongo`` integration. diff --git a/releasenotes/notes/span-args-remove-5feecae6cf00537f.yaml b/releasenotes/notes/span-args-remove-5feecae6cf00537f.yaml new file mode 100644 index 00000000000..03d65342e97 --- /dev/null +++ b/releasenotes/notes/span-args-remove-5feecae6cf00537f.yaml @@ -0,0 +1,4 @@ +--- +other: + - | + This change removes deprecated methods and method parameters from the `Span` class. diff --git a/riotfile.py b/riotfile.py index b8144914b9f..a5981542df4 100644 --- a/riotfile.py +++ b/riotfile.py @@ -1633,26 +1633,6 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT ), ], ), - Venv( - name="mongoengine", - command="pytest {cmdargs} tests/contrib/mongoengine", - pkgs={ - # pymongo v4.9.0 introduced breaking changes that are not yet supported by mongoengine - "pymongo": "<4.9.0", - "pytest-randomly": latest, - }, - venvs=[ - Venv( - pys="3.8", - pkgs={"mongoengine": ["~=0.23.0", latest]}, - ), - Venv( - # mongoengine added support for Python 3.9/3.10 in 0.24 - pys=select_pys(min_version="3.9"), - pkgs={"mongoengine": ["~=0.24.0", "~=0.24", latest]}, - ), - ], - ), Venv( name="asgi", pkgs={ @@ -2171,12 +2151,6 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT ), ], ), - Venv( - name="cassandra", - pys="3.8", # see https://github.com/r4fek/django-cassandra-engine/issues/104 - pkgs={"cassandra-driver": ["~=3.24.0", latest], "pytest-randomly": latest}, - command="pytest {cmdargs} tests/contrib/cassandra", - ), Venv( name="algoliasearch", command="pytest {cmdargs} tests/contrib/algoliasearch", diff --git a/supported_versions_output.json b/supported_versions_output.json index c1ea2d658ad..54d2847881a 100644 --- a/supported_versions_output.json +++ b/supported_versions_output.json @@ -106,7 +106,7 @@ "minimum_tracer_supported": "5.12.2", "max_tracer_supported": "5.15.0", "pinned": "true", - "auto-instrumented": false + "auto-instrumented": true }, { "dependency": "azure-functions", @@ -147,13 +147,6 @@ "max_tracer_supported": "0.13.4", "auto-instrumented": true }, - { - "dependency": "cassandra-driver", - "integration": "cassandra", - "minimum_tracer_supported": "3.24.0", - "max_tracer_supported": "3.28.0", - "auto-instrumented": true - }, { "dependency": "celery", "integration": "celery", @@ -464,13 +457,6 @@ "max_tracer_supported": "1.0.2", "auto-instrumented": true }, - { - "dependency": "mongoengine", - "integration": "mongoengine", - "minimum_tracer_supported": "0.23.1", - "max_tracer_supported": "0.29.1", - "auto-instrumented": true - }, { "dependency": "mysql-connector-python", "integration": "mysql", @@ -489,7 +475,8 @@ "dependency": "openai", "integration": "openai", "minimum_tracer_supported": "1.0.0", - "max_tracer_supported": "1.91.0", + "max_tracer_supported": "1.109.1", + "pinned": "true", "auto-instrumented": true }, { diff --git a/supported_versions_table.csv b/supported_versions_table.csv index 94af82316ad..1da57e9f537 100644 --- a/supported_versions_table.csv +++ b/supported_versions_table.csv @@ -13,13 +13,12 @@ asyncpg,asyncpg,0.22.0,0.30.0,True avro,avro,1.12.0,1.12.0,True datadog-lambda,aws_lambda,6.105.0,6.105.0,True datadog_lambda,aws_lambda,6.105.0,6.105.0,True -azure-eventhub,azure_eventhubs *,5.12.2,5.15.0,False +azure-eventhub,azure_eventhubs *,5.12.2,5.15.0,True azure-functions,azure_functions *,1.10.1,1.23.0,True azure-servicebus,azure_servicebus *,7.14.2,7.14.2,True boto3,botocore *,1.34.49,1.38.26,True botocore,botocore *,1.34.49,1.38.26,True bottle,bottle,0.12.25,0.13.4,True -cassandra-driver,cassandra,3.24.0,3.28.0,True celery,celery,5.5.3,5.5.3,True cherrypy,cherrypy,17.0.0,18.10.0,False python-consul,consul,1.1.0,1.1.0,True @@ -64,10 +63,9 @@ mako,mako,1.0.14,1.3.10,True mariadb,mariadb,1.0.11,1.1.13,True mcp,mcp,1.10.1,1.16.0,True molten,molten,1.0.2,1.0.2,True -mongoengine,mongoengine,0.23.1,0.29.1,True mysql-connector-python,mysql,8.0.5,9.4.0,True mysqlclient,mysqldb,2.2.1,2.2.6,True -openai,openai,1.0.0,1.91.0,True +openai,openai *,1.0.0,1.109.1,True openai-agents,openai_agents,0.0.8,0.0.16,True protobuf,protobuf,5.29.3,6.32.0,False psycopg,psycopg,3.0.18,3.2.10,True diff --git a/tests/commands/ddtrace_run_app_name.py b/tests/commands/ddtrace_run_app_name.py deleted file mode 100644 index 4cf41192e79..00000000000 --- a/tests/commands/ddtrace_run_app_name.py +++ /dev/null @@ -1,6 +0,0 @@ -from ddtrace.opentracer import Tracer - - -if __name__ == "__main__": - tracer = Tracer() - print(tracer._service_name) diff --git a/tests/commands/test_runner.py b/tests/commands/test_runner.py index 967db4a7f5e..4b29dff8ea3 100644 --- a/tests/commands/test_runner.py +++ b/tests/commands/test_runner.py @@ -197,13 +197,6 @@ def test_argv_passed(self): out = subprocess.check_output(["ddtrace-run", "python", "tests/commands/ddtrace_run_argv.py", "foo", "bar"]) assert out.startswith(b"Test success") - def test_got_app_name(self): - """ - apps run with ddtrace-run have a proper app name - """ - out = subprocess.check_output(["ddtrace-run", "python", "tests/commands/ddtrace_run_app_name.py"]) - assert out.startswith(b"ddtrace_run_app_name.py") - def test_global_trace_tags(self): """Ensure global tags are passed in from environment""" with self.override_env(dict(DD_TRACE_GLOBAL_TAGS="a:True,b:0,c:C")): diff --git a/tests/contrib/aiobotocore/test.py b/tests/contrib/aiobotocore/test.py index 5e7151797b0..0fdf25414e8 100644 --- a/tests/contrib/aiobotocore/test.py +++ b/tests/contrib/aiobotocore/test.py @@ -303,92 +303,6 @@ async def test_double_patch(tracer): assert len(traces[0]) == 1 -@pytest.mark.asyncio -async def test_opentraced_client(tracer): - from tests.opentracer.utils import init_tracer - - ot_tracer = init_tracer("my_svc", tracer) - - with ot_tracer.start_active_span("ot_outer_span"): - async with aiobotocore_client("ec2", tracer) as ec2: - await ec2.describe_instances() - - traces = tracer.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - ot_span = traces[0][0] - dd_span = traces[0][1] - - assert ot_span.resource == "ot_outer_span" - assert ot_span.service == "my_svc" - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert_is_measured(dd_span) - assert dd_span.get_tag("aws.agent") == "aiobotocore" - assert dd_span.get_tag("aws.region") == "us-west-2" - assert dd_span.get_tag("region") == "us-west-2" - assert dd_span.get_tag("aws.operation") == "DescribeInstances" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_metric("retry_attempts") == 0 - assert dd_span.service == "aws.ec2" - assert dd_span.resource == "ec2.describeinstances" - assert dd_span.name == "ec2.command" - assert dd_span.get_tag("component") == "aiobotocore" - assert dd_span.get_tag("span.kind") == "client" - - -@pytest.mark.asyncio -async def test_opentraced_s3_client(tracer): - from tests.opentracer.utils import init_tracer - - ot_tracer = init_tracer("my_svc", tracer) - - with ot_tracer.start_active_span("ot_outer_span"): - async with aiobotocore_client("s3", tracer) as s3: - await s3.list_buckets() - with ot_tracer.start_active_span("ot_inner_span1"): - await s3.list_buckets() - with ot_tracer.start_active_span("ot_inner_span2"): - pass - - traces = tracer.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 5 - ot_outer_span = traces[0][0] - dd_span = traces[0][1] - ot_inner_span = traces[0][2] - dd_span2 = traces[0][3] - ot_inner_span2 = traces[0][4] - - assert ot_outer_span.resource == "ot_outer_span" - assert ot_inner_span.resource == "ot_inner_span1" - assert ot_inner_span2.resource == "ot_inner_span2" - - # confirm the parenting - assert ot_outer_span.parent_id is None - assert dd_span.parent_id == ot_outer_span.span_id - assert ot_inner_span.parent_id == ot_outer_span.span_id - assert dd_span2.parent_id == ot_inner_span.span_id - assert ot_inner_span2.parent_id == ot_outer_span.span_id - - assert_is_measured(dd_span) - assert dd_span.get_tag("aws.operation") == "ListBuckets" - assert_span_http_status_code(dd_span, 200) - assert dd_span.service == "aws.s3" - assert dd_span.resource == "s3.listbuckets" - assert dd_span.name == "s3.command" - - assert dd_span2.get_tag("aws.operation") == "ListBuckets" - assert_span_http_status_code(dd_span2, 200) - assert dd_span2.service == "aws.s3" - assert dd_span2.resource == "s3.listbuckets" - assert dd_span2.name == "s3.command" - assert dd_span.get_tag("component") == "aiobotocore" - - @pytest.mark.asyncio async def test_user_specified_service(tracer): """ diff --git a/tests/contrib/aiohttp/test_middleware.py b/tests/contrib/aiohttp/test_middleware.py index 37e6ea2e3de..e067c197685 100644 --- a/tests/contrib/aiohttp/test_middleware.py +++ b/tests/contrib/aiohttp/test_middleware.py @@ -1,6 +1,5 @@ import os -from opentracing.scope_managers.asyncio import AsyncioScopeManager import pytest import pytest_asyncio @@ -14,7 +13,6 @@ from ddtrace.contrib.internal.aiohttp.middlewares import trace_middleware from ddtrace.ext import http from ddtrace.internal.utils.version import parse_version -from tests.opentracer.utils import init_tracer from tests.tracer.utils_inferred_spans.test_helpers import assert_web_and_inferred_aws_api_gateway_span_data from tests.utils import assert_span_http_status_code from tests.utils import override_global_config @@ -545,22 +543,6 @@ async def test_parenting_200_dd(app_tracer, aiohttp_client): _assert_200_parenting(client, traces) -async def test_parenting_200_ot(app_tracer, aiohttp_client): - """OpenTracing version of test_handler.""" - app, tracer = app_tracer - client = await aiohttp_client(app) - ot_tracer = init_tracer("aiohttp_svc", tracer, scope_manager=AsyncioScopeManager()) - - with ot_tracer.start_active_span("aiohttp_op"): - request = await client.request("GET", "/") - assert 200 == request.status - text = await request.text() - - assert "What's tracing?" == text - traces = tracer.pop_traces() - _assert_200_parenting(client, traces) - - @pytest.mark.parametrize( "test_app", [ diff --git a/tests/contrib/aiopg/test.py b/tests/contrib/aiopg/test.py index b60e5989dda..63f2b89a379 100644 --- a/tests/contrib/aiopg/test.py +++ b/tests/contrib/aiopg/test.py @@ -11,7 +11,6 @@ from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from tests.contrib.asyncio.utils import AsyncioTestCase from tests.contrib.config import POSTGRES_CONFIG -from tests.opentracer.utils import init_tracer from tests.subprocesstest import run_in_subprocess from tests.utils import assert_is_measured @@ -75,29 +74,6 @@ async def assert_conn_is_traced(self, tracer, db, service): assert span.get_tag("component") == "aiopg" assert span.get_tag("span.kind") == "client" - # Ensure OpenTracing compatibility - ot_tracer = init_tracer("aiopg_svc", tracer) - with ot_tracer.start_active_span("aiopg_op"): - cursor = await db.cursor() - await cursor.execute(q) - rows = await cursor.fetchall() - assert rows == [("foobarblah",)] - spans = self.pop_spans() - assert len(spans) == 2 - ot_span, dd_span = spans - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - assert ot_span.name == "aiopg_op" - assert ot_span.service == "aiopg_svc" - assert dd_span.name == "postgres.query" - assert dd_span.resource == q - assert dd_span.service == service - assert dd_span.error == 0 - assert dd_span.span_type == "sql" - assert dd_span.get_tag("component") == "aiopg" - assert span.get_tag("span.kind") == "client" - # run a query with an error and ensure all is well q = "select * from some_non_existant_table" cur = await db.cursor() diff --git a/tests/contrib/aredis/test_aredis.py b/tests/contrib/aredis/test_aredis.py index c1ae507aae5..a05e70fcdb4 100644 --- a/tests/contrib/aredis/test_aredis.py +++ b/tests/contrib/aredis/test_aredis.py @@ -9,7 +9,6 @@ from ddtrace.contrib.internal.aredis.patch import unpatch from ddtrace.internal.compat import is_wrapted from tests.conftest import DEFAULT_DDTRACE_SUBPROCESS_TEST_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import override_config from ..config import REDIS_CONFIG @@ -185,19 +184,6 @@ async def test(tracer, test_spans): assert err == b"", err.decode() -@pytest.mark.asyncio -async def test_opentracing(tracer, snapshot_context): - """Ensure OpenTracing works with redis.""" - - with snapshot_context(): - r = aredis.StrictRedis(port=REDIS_CONFIG["port"]) - pin = Pin.get_from(r) - ot_tracer = init_tracer("redis_svc", pin.tracer) - - with ot_tracer.start_active_span("redis_get"): - await r.get("cheese") - - @pytest.mark.subprocess(ddtrace_run=True, env=dict(DD_REDIS_RESOURCE_ONLY_COMMAND="false")) @pytest.mark.snapshot def test_full_command_in_resource_env(): diff --git a/tests/contrib/asyncio/test_propagation.py b/tests/contrib/asyncio/test_propagation.py index fd962e544ea..fc976d59ea8 100644 --- a/tests/contrib/asyncio/test_propagation.py +++ b/tests/contrib/asyncio/test_propagation.py @@ -7,7 +7,6 @@ from ddtrace.contrib.internal.asyncio.patch import patch from ddtrace.contrib.internal.asyncio.patch import unpatch from ddtrace.trace import Context -from tests.opentracer.utils import init_tracer _orig_create_task = asyncio.BaseEventLoop.create_task @@ -115,59 +114,3 @@ async def test_propagation_with_new_context(tracer): span = traces[0][0] assert span.trace_id == 100 assert span.parent_id == 101 - - -@pytest.mark.asyncio -async def test_trace_multiple_coroutines_ot_outer(tracer): - """OpenTracing version of test_trace_multiple_coroutines.""" - - # if multiple coroutines have nested tracing, they must belong - # to the same trace - async def coro(): - # another traced coroutine - with tracer.trace("coroutine_2"): - return 42 - - ot_tracer = init_tracer("asyncio_svc", tracer) - with ot_tracer.start_active_span("coroutine_1"): - value = await coro() - - # the coroutine has been called correctly - assert 42 == value - # a single trace has been properly reported - traces = tracer.pop_traces() - assert 1 == len(traces) - assert 2 == len(traces[0]) - assert "coroutine_1" == traces[0][0].name - assert "coroutine_2" == traces[0][1].name - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id - - -@pytest.mark.asyncio -async def test_trace_multiple_coroutines_ot_inner(tracer): - """OpenTracing version of test_trace_multiple_coroutines.""" - # if multiple coroutines have nested tracing, they must belong - # to the same trace - ot_tracer = init_tracer("asyncio_svc", tracer) - - async def coro(): - # another traced coroutine - with ot_tracer.start_active_span("coroutine_2"): - return 42 - - with tracer.trace("coroutine_1"): - value = await coro() - - # the coroutine has been called correctly - assert 42 == value - # a single trace has been properly reported - traces = tracer.pop_traces() - assert 1 == len(traces) - assert 2 == len(traces[0]) - assert "coroutine_1" == traces[0][0].name - assert "coroutine_2" == traces[0][1].name - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id diff --git a/tests/contrib/boto/test.py b/tests/contrib/boto/test.py index 91c626e6cbc..76dd974692a 100644 --- a/tests/contrib/boto/test.py +++ b/tests/contrib/boto/test.py @@ -20,7 +20,6 @@ from ddtrace.contrib.internal.boto.patch import unpatch from ddtrace.ext import http from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -759,56 +758,3 @@ def test_elasticache_client(self): self.assertEqual(span.get_tag("span.kind"), "client") self.assertEqual(span.service, "test-boto-tracing.elasticache") self.assertEqual(span.resource, "elasticache") - - @mock_ec2 - def test_ec2_client_ot(self): - """OpenTracing compatibility check of the test_ec2_client test.""" - ec2 = boto.ec2.connect_to_region("us-west-2") - ot_tracer = init_tracer("my_svc", self.tracer) - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = self.tracer - pin.onto(ec2) - - with ot_tracer.start_active_span("ot_span"): - ec2.get_all_instances() - spans = self.pop_spans() - assert spans - self.assertEqual(len(spans), 2) - ot_span, dd_span = spans - - # confirm the parenting - self.assertIsNone(ot_span.parent_id) - self.assertEqual(dd_span.parent_id, ot_span.span_id) - - self.assertEqual(ot_span.resource, "ot_span") - self.assertEqual(dd_span.get_tag("aws.operation"), "DescribeInstances") - self.assertEqual(dd_span.get_tag("component"), "boto") - self.assertEqual(dd_span.get_tag("span.kind"), "client") - assert_span_http_status_code(dd_span, 200) - self.assertEqual(dd_span.get_tag(http.METHOD), "POST") - self.assertEqual(dd_span.get_tag("aws.region"), "us-west-2") - self.assertEqual(dd_span.get_tag("region"), "us-west-2") - self.assertEqual(dd_span.get_tag("aws.partition"), "aws") - - with ot_tracer.start_active_span("ot_span"): - ec2.run_instances(21) - spans = self.pop_spans() - assert spans - self.assertEqual(len(spans), 2) - ot_span, dd_span = spans - - # confirm the parenting - self.assertIsNone(ot_span.parent_id) - self.assertEqual(dd_span.parent_id, ot_span.span_id) - - self.assertEqual(dd_span.get_tag("aws.operation"), "RunInstances") - assert_span_http_status_code(dd_span, 200) - self.assertEqual(dd_span.get_tag(http.METHOD), "POST") - self.assertEqual(dd_span.get_tag("aws.region"), "us-west-2") - self.assertEqual(dd_span.get_tag("region"), "us-west-2") - self.assertEqual(dd_span.get_tag("aws.partition"), "aws") - self.assertEqual(dd_span.get_tag("component"), "boto") - self.assertEqual(dd_span.get_tag("span.kind"), "client") - self.assertEqual(dd_span.service, "test-boto-tracing.ec2") - self.assertEqual(dd_span.resource, "ec2.runinstances") - self.assertEqual(dd_span.name, "ec2.command") diff --git a/tests/contrib/botocore/test.py b/tests/contrib/botocore/test.py index 5270f69f021..1cfdb2306fd 100644 --- a/tests/contrib/botocore/test.py +++ b/tests/contrib/botocore/test.py @@ -47,7 +47,6 @@ from ddtrace.internal.utils.version import parse_version from ddtrace.propagation.http import HTTP_HEADER_PARENT_ID from ddtrace.propagation.http import HTTP_HEADER_TRACE_ID -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -2245,43 +2244,6 @@ def test_schematized_unspecified_service_kms_client_v1(self): assert span.service == DEFAULT_SPAN_SERVICE_NAME assert span.name == "aws.kms.request" - @mock_ec2 - def test_traced_client_ot(self): - """OpenTracing version of test_traced_client.""" - ot_tracer = init_tracer("ec2_svc", self.tracer) - - with ot_tracer.start_active_span("ec2_op"): - ec2 = self.session.create_client("ec2", region_name="us-west-2") - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = self.tracer - pin.onto(ec2) - ec2.describe_instances() - - spans = self.get_spans() - assert spans - assert len(spans) == 2 - - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "ec2_op" - assert ot_span.service == "ec2_svc" - - assert dd_span.get_tag("aws.agent") == "botocore" - assert dd_span.get_tag("aws.region") == "us-west-2" - assert dd_span.get_tag("region") == "us-west-2" - assert dd_span.get_tag("aws.operation") == "DescribeInstances" - assert dd_span.get_tag("component") == "botocore" - assert dd_span.get_tag("span.kind"), "client" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_metric("retry_attempts") == 0 - assert dd_span.service == "test-botocore-tracing.ec2" - assert dd_span.resource == "ec2.describeinstances" - assert dd_span.name == "ec2.command" - @unittest.skipIf(BOTOCORE_VERSION < (1, 9, 0), "Skipping for older versions of botocore without Stubber") def test_stubber_no_response_metadata(self): """When no ResponseMetadata key is provided in the response""" diff --git a/tests/contrib/bottle/test.py b/tests/contrib/bottle/test.py index 5a274802d85..d74ceb4935d 100644 --- a/tests/contrib/bottle/test.py +++ b/tests/contrib/bottle/test.py @@ -7,7 +7,6 @@ from ddtrace.contrib.internal.bottle.patch import TracePlugin from ddtrace.ext import http from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.tracer.utils_inferred_spans.test_helpers import assert_web_and_inferred_aws_api_gateway_span_data from tests.utils import TracerTestCase from tests.utils import assert_is_measured @@ -316,44 +315,6 @@ def home(): assert s.get_tag("span.kind") == "server" assert s.get_tag("http.route") == "/home/" - def test_200_ot(self): - ot_tracer = init_tracer("my_svc", self.tracer) - - # setup our test app - @self.app.route("/hi/") - def hi(name): - return "hi %s" % name - - self._trace_app(self.tracer) - - # make a request - with ot_tracer.start_active_span("ot_span"): - resp = self.app.get("/hi/dougie") - - assert resp.status_int == 200 - assert resp.body.decode("utf-8", errors="ignore") == "hi dougie" - # validate it's traced - spans = self.pop_spans() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.resource == "ot_span" - - assert_is_measured(dd_span) - assert dd_span.name == "bottle.request" - assert dd_span.service == "bottle-app" - assert dd_span.resource == "GET /hi/" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_tag("http.method") == "GET" - assert dd_span.get_tag(http.URL) == "http://localhost:80/hi/dougie" - assert dd_span.get_tag("component") == "bottle" - assert dd_span.get_tag("span.kind") == "server" - assert dd_span.get_tag("http.route") == "/hi/" - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) def test_user_specified_service_default_schema(self): """ diff --git a/tests/contrib/cassandra/__init__.py b/tests/contrib/cassandra/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/contrib/cassandra/test.py b/tests/contrib/cassandra/test.py deleted file mode 100644 index 708d599040a..00000000000 --- a/tests/contrib/cassandra/test.py +++ /dev/null @@ -1,546 +0,0 @@ -import contextlib -import logging -from threading import Event -import unittest - -from cassandra.cluster import Cluster -from cassandra.cluster import ResultSet -from cassandra.query import BatchStatement -from cassandra.query import SimpleStatement -import mock - -from ddtrace import config -from ddtrace._trace.pin import Pin -from ddtrace.constants import ERROR_MSG -from ddtrace.constants import ERROR_TYPE -from ddtrace.contrib.internal.cassandra.patch import patch -from ddtrace.contrib.internal.cassandra.patch import unpatch -from ddtrace.contrib.internal.cassandra.session import SERVICE -from ddtrace.ext import cassandra as cassx -from ddtrace.ext import net -from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.contrib.config import CASSANDRA_CONFIG -from tests.opentracer.utils import init_tracer -from tests.utils import DummyTracer -from tests.utils import TracerTestCase -from tests.utils import assert_is_measured - - -# Oftentimes our tests fails because Cassandra connection timeouts during keyspace drop. Slowness in keyspace drop -# is known and is due to 'auto_snapshot' configuration. In our test env we should disable it, but the official cassandra -# image that we are using only allows us to configure a few configs: -# https://github.com/docker-library/cassandra/blob/4474c6c5cc2a81ee57c5615aae00555fca7e26a6/3.11/docker-entrypoint.sh#L51 -# So for now we just increase the timeout, if this is not enough we may want to extend the official image with our own -# custom image. -CONNECTION_TIMEOUT_SECS = 20 # override the default value of 5 - -logging.getLogger("cassandra").setLevel(logging.INFO) - - -def _setup(testObject): - self = testObject or mock.Mock() - - # skip all the modules if the Cluster is not available - if not Cluster: - raise unittest.SkipTest("cassandra.cluster.Cluster is not available.") - - # create the KEYSPACE for this test module - self.cluster = Cluster(port=CASSANDRA_CONFIG["port"], connect_timeout=CONNECTION_TIMEOUT_SECS) - self.session = self.cluster.connect() - self.session.execute("DROP KEYSPACE IF EXISTS test", timeout=10) - self.session.execute( - "CREATE KEYSPACE if not exists test WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor': 1};" # noqa:E501 - ) - self.session.execute("CREATE TABLE if not exists test.person (name text PRIMARY KEY, age int, description text)") - self.session.execute( - "CREATE TABLE if not exists test.person_write (name text PRIMARY KEY, age int, description text)" - ) - self.session.execute( - "INSERT INTO test.person (name, age, description) VALUES ('Cassandra', 100, 'A cruel mistress')" - ) - self.session.execute( - "INSERT INTO test.person (name, age, description) VALUES ('Athena', 100, 'Whose shield is thunder')" - ) - self.session.execute( - "INSERT INTO test.person (name, age, description) VALUES ('Calypso', 100, 'Softly-braided nymph')" - ) - - -def _teardown(testObject): - self = testObject or mock.Mock() - # destroy the KEYSPACE - self.session.execute("DROP TABLE IF EXISTS test.person") - self.session.execute("DROP TABLE IF EXISTS test.person_write") - self.session.execute("DROP KEYSPACE IF EXISTS test", timeout=10) - - -def setUpModule(): - _setup(None) - - -def tearDownModule(): - _teardown(None) - - -class CassandraBase(object): - """ - Needs a running Cassandra - """ - - TEST_QUERY = "SELECT * from test.person WHERE name = 'Cassandra'" - TEST_QUERY_PAGINATED = "SELECT * from test.person" - TEST_KEYSPACE = "test" - TEST_PORT = CASSANDRA_CONFIG["port"] - TEST_SERVICE = "test-cassandra" - - def setUp(self): - _setup(self) - - def tearDown(self): - _teardown(self) - - @contextlib.contextmanager - def override_config(self, integration, values): - """ - Temporarily override an integration configuration value - >>> with self.override_config('flask', dict(service_name='test-service')): - ... # Your test - """ - options = getattr(config, integration) - - original = dict((key, options.get(key)) for key in values.keys()) - - options.update(values) - try: - yield - finally: - options.update(original) - - def _assert_result_correct(self, result): - assert len(result.current_rows) == 1 - for r in result: - assert r.name == "Cassandra" - assert r.age == 100 - assert r.description == "A cruel mistress" - - def _test_query_base(self, execute_fn): - session, tracer = self._traced_session() - - result = execute_fn(session, self.TEST_QUERY) - self._assert_result_correct(result) - - spans = tracer.pop() - assert spans, spans - - # another for the actual query - assert len(spans) == 1 - - query = spans[0] - - assert_is_measured(query) - assert query.service == self.TEST_SERVICE - assert query.resource == self.TEST_QUERY - assert query.span_type == "cassandra" - - assert query.get_tag(cassx.KEYSPACE) == self.TEST_KEYSPACE - assert query.get_metric("db.row_count") == 1 - assert query.get_metric("network.destination.port") == self.TEST_PORT - assert query.get_tag(cassx.PAGE_NUMBER) is None - assert query.get_tag(cassx.PAGINATED) == "False" - assert query.get_tag(net.TARGET_HOST) == "127.0.0.1" - assert query.get_tag(net.SERVER_ADDRESS) == "127.0.0.1" - assert query.get_tag("component") == "cassandra" - assert query.get_tag("span.kind") == "client" - assert query.get_tag("db.system") == "cassandra" - - def test_query(self): - def execute_fn(session, query): - return session.execute(query) - - self._test_query_base(execute_fn) - - def test_query_ot(self): - """Ensure that cassandra works with the opentracer.""" - - def execute_fn(session, query): - return session.execute(query) - - session, tracer = self._traced_session() - ot_tracer = init_tracer("cass_svc", tracer) - - with ot_tracer.start_active_span("cass_op"): - result = execute_fn(session, self.TEST_QUERY) - self._assert_result_correct(result) - - spans = tracer.pop() - assert spans, spans - - # another for the actual query - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "cass_op" - assert ot_span.service == "cass_svc" - - assert dd_span.service == self.TEST_SERVICE - assert dd_span.resource == self.TEST_QUERY - assert dd_span.span_type == "cassandra" - - assert dd_span.get_tag(cassx.KEYSPACE) == self.TEST_KEYSPACE - assert dd_span.get_metric("db.row_count") == 1 - assert dd_span.get_metric("network.destination.port") == self.TEST_PORT - assert dd_span.get_tag(cassx.PAGE_NUMBER) is None - assert dd_span.get_tag(cassx.PAGINATED) == "False" - assert dd_span.get_tag(net.TARGET_HOST) == "127.0.0.1" - assert dd_span.get_tag(net.SERVER_ADDRESS) == "127.0.0.1" - assert dd_span.get_tag("component") == "cassandra" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.get_tag("db.system") == "cassandra" - - def test_query_async(self): - def execute_fn(session, query): - event = Event() - result = [] - future = session.execute_async(query) - - def callback(results): - result.append(ResultSet(future, results)) - event.set() - - future.add_callback(callback) - event.wait() - return result[0] - - self._test_query_base(execute_fn) - - def test_query_async_clearing_callbacks(self): - def execute_fn(session, query): - future = session.execute_async(query) - future.clear_callbacks() - return future.result() - - self._test_query_base(execute_fn) - - def test_span_is_removed_from_future(self): - session, tracer = self._traced_session() - future = session.execute_async(self.TEST_QUERY) - future.result() - span = getattr(future, "_ddtrace_current_span", None) - assert span is None - - def test_paginated_query(self): - session, tracer = self._traced_session() - - statement = SimpleStatement(self.TEST_QUERY_PAGINATED, fetch_size=1) - result = session.execute(statement) - # iterate over all pages - results = list(result) - assert len(results) == 3 - - spans = tracer.pop() - assert spans, spans - - # There are 4 spans for 3 results since the driver makes a request with - # no result to check that it has reached the last page - assert len(spans) == 4 - - for i in range(4): - query = spans[i] - assert query.service == self.TEST_SERVICE - assert query.resource == self.TEST_QUERY_PAGINATED - assert query.span_type == "cassandra" - - assert query.get_tag(cassx.KEYSPACE) == self.TEST_KEYSPACE - assert query.get_metric("network.destination.port") == self.TEST_PORT - if i == 3: - assert query.get_metric("db.row_count") == 0 - else: - assert query.get_metric("db.row_count") == 1 - assert query.get_tag(net.TARGET_HOST) == "127.0.0.1" - assert query.get_tag(net.SERVER_ADDRESS) == "127.0.0.1" - assert query.get_tag(cassx.PAGINATED) == "True" - assert query.get_metric(cassx.PAGE_NUMBER) == i + 1 - assert query.get_tag("db.system") == "cassandra" - - def test_trace_with_service(self): - session, tracer = self._traced_session() - - session.execute(self.TEST_QUERY) - spans = tracer.pop() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.service == self.TEST_SERVICE - - def test_trace_error(self): - session, tracer = self._traced_session() - - try: - session.execute("select * from test.i_dont_exist limit 1") - except Exception: - pass - else: - assert 0 - - spans = tracer.pop() - assert spans - query = spans[0] - assert query.error == 1 - for k in (ERROR_MSG, ERROR_TYPE): - assert query.get_tag(k) - - def test_bound_statement(self): - session, tracer = self._traced_session() - - query = "INSERT INTO test.person_write (name, age, description) VALUES (?, ?, ?)" - prepared = session.prepare(query) - session.execute(prepared, ("matt", 34, "can")) - - prepared = session.prepare(query) - bound_stmt = prepared.bind(("leo", 16, "fr")) - session.execute(bound_stmt) - - spans = tracer.pop() - assert len(spans) == 2 - for s in spans: - assert s.resource == query - - def test_batch_statement(self): - session, tracer = self._traced_session() - - batch = BatchStatement() - batch.add( - SimpleStatement("INSERT INTO test.person_write (name, age, description) VALUES (%s, %s, %s)"), - ("Joe", 1, "a"), - ) - batch.add( - SimpleStatement("INSERT INTO test.person_write (name, age, description) VALUES (%s, %s, %s)"), - ("Jane", 2, "b"), - ) - session.execute(batch) - - spans = tracer.pop() - assert len(spans) == 1 - s = spans[0] - assert s.resource == "BatchStatement" - assert s.get_metric("cassandra.batch_size") == 2 - assert "test.person" in s.get_tag("cassandra.query") - - def test_batched_bound_statement(self): - session, tracer = self._traced_session() - - batch = BatchStatement() - - prepared_statement = session.prepare("INSERT INTO test.person_write (name, age, description) VALUES (?, ?, ?)") - batch.add(prepared_statement.bind(("matt", 34, "can"))) - session.execute(batch) - - spans = tracer.pop() - assert len(spans) == 1 - s = spans[0] - assert s.resource == "BatchStatement" - assert s.get_tag("cassandra.query") == "" - - -class TestCassPatchDefault(unittest.TestCase, CassandraBase): - """Test Cassandra instrumentation with patching and default configuration""" - - TEST_SERVICE = SERVICE - - def tearDown(self): - unpatch() - - def setUp(self): - CassandraBase.setUp(self) - patch() - - def _traced_session(self): - tracer = DummyTracer() - Pin.get_from(self.cluster)._clone(tracer=tracer).onto(self.cluster) - return self.cluster.connect(self.TEST_KEYSPACE), tracer - - -class TestCassPatchAll(TestCassPatchDefault): - """Test Cassandra instrumentation with patching and custom service on all clusters""" - - TEST_SERVICE = "test-cassandra-patch-all" - - def tearDown(self): - unpatch() - - def setUp(self): - CassandraBase.setUp(self) - patch() - - def _traced_session(self): - tracer = DummyTracer() - # pin the global Cluster to test if they will conflict - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = tracer - pin.onto(Cluster) - self.cluster = Cluster(port=CASSANDRA_CONFIG["port"]) - - return self.cluster.connect(self.TEST_KEYSPACE), tracer - - -class TestCassPatchOne(TestCassPatchDefault): - """Test Cassandra instrumentation with patching and custom service on one cluster""" - - TEST_SERVICE = "test-cassandra-patch-one" - - def tearDown(self): - unpatch() - - def setUp(self): - CassandraBase.setUp(self) - patch() - - def _traced_session(self): - tracer = DummyTracer() - # pin the global Cluster to test if they will conflict - Pin(service="not-%s" % self.TEST_SERVICE).onto(Cluster) - self.cluster = Cluster(port=CASSANDRA_CONFIG["port"]) - - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = tracer - pin.onto(self.cluster) - return self.cluster.connect(self.TEST_KEYSPACE), tracer - - def test_patch_unpatch(self): - # Test patch idempotence - patch() - patch() - - tracer = DummyTracer() - Pin.get_from(Cluster)._clone(tracer=tracer).onto(Cluster) - - session = Cluster(port=CASSANDRA_CONFIG["port"]).connect(self.TEST_KEYSPACE) - session.execute(self.TEST_QUERY) - - spans = tracer.pop() - assert spans, spans - assert len(spans) == 1 - - # Test unpatch - unpatch() - - session = Cluster(port=CASSANDRA_CONFIG["port"]).connect(self.TEST_KEYSPACE) - session.execute(self.TEST_QUERY) - - spans = tracer.pop() - assert not spans, spans - - # Test patch again - patch() - Pin.get_from(Cluster)._clone(tracer=tracer).onto(Cluster) - - session = Cluster(port=CASSANDRA_CONFIG["port"]).connect(self.TEST_KEYSPACE) - session.execute(self.TEST_QUERY) - - spans = tracer.pop() - assert spans, spans - - -class TestCassandraConfig(TracerTestCase): - """ - Test various configurations of the Cassandra integration. - """ - - TEST_QUERY = "SELECT * from test.person WHERE name = 'Cassandra'" - TEST_KEYSPACE = "test" - - def setUp(self): - super(TestCassandraConfig, self).setUp() - patch() - self.tracer = DummyTracer() - self.cluster = Cluster(port=CASSANDRA_CONFIG["port"]) - Pin.get_from(self.cluster)._clone(tracer=self.tracer).onto(self.cluster) - self.session = self.cluster.connect(self.TEST_KEYSPACE) - - def tearDown(self): - unpatch() - super(TestCassandraConfig, self).tearDown() - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc", DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) - def test_user_specified_service_v0(self): - """ - v0: When a user specifies a service for the app - The cassandra integration should not use it. - """ - # Ensure that the service name was configured - from ddtrace import config - - assert config.service == "mysvc" - - self.session.execute(self.TEST_QUERY) - spans = self.pop_spans() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.service != "mysvc" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc", DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) - def test_user_specified_service_v1(self): - """ - v1: When a user specifies a service for the app - The cassandra integration should use it. - """ - # Ensure that the service name was configured - from ddtrace import config - - assert config.service == "mysvc" - - self.session.execute(self.TEST_QUERY) - spans = self.pop_spans() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.service == "mysvc" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) - def test_unspecified_service_v1(self): - """ - v1: When a user does not specify a service for the app - dd-trace-py should default to internal.schema.DEFAULT_SPAN_SERVICE_NAME - """ - # Ensure that the service name was configured - from ddtrace import config - - assert config.service == DEFAULT_SPAN_SERVICE_NAME - - self.session.execute(self.TEST_QUERY) - spans = self.pop_spans() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.service == DEFAULT_SPAN_SERVICE_NAME - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) - def test_span_name_v0_schema(self): - """ - When a user specifies a service for the app - The cassandra integration should not use it. - """ - self.session.execute(self.TEST_QUERY) - spans = self.pop_spans() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.name == "cassandra.query" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) - def test_span_name_v1_schema(self): - """ - When a user specifies a service for the app - The cassandra integration should not use it. - """ - self.session.execute(self.TEST_QUERY) - spans = self.pop_spans() - assert spans - assert len(spans) == 1 - query = spans[0] - assert query.name == "cassandra.query" diff --git a/tests/contrib/cassandra/test_cassandra_patch.py b/tests/contrib/cassandra/test_cassandra_patch.py deleted file mode 100644 index 19a09daccf4..00000000000 --- a/tests/contrib/cassandra/test_cassandra_patch.py +++ /dev/null @@ -1,31 +0,0 @@ -# This test script was automatically generated by the contrib-patch-tests.py -# script. If you want to make changes to it, you should make sure that you have -# removed the ``_generated`` suffix from the file name, to prevent the content -# from being overwritten by future re-generations. - -from ddtrace.contrib.internal.cassandra.patch import patch -from ddtrace.contrib.internal.cassandra.session import get_version - - -try: - from ddtrace.contrib.internal.cassandra.patch import unpatch -except ImportError: - unpatch = None -from tests.contrib.patch import PatchTestCase - - -class TestCassandraPatch(PatchTestCase.Base): - __integration_name__ = "cassandra" - __module_name__ = "cassandra.cluster" - __patch_func__ = patch - __unpatch_func__ = unpatch - __get_version__ = get_version - - def assert_module_patched(self, cassandra_cluster): - pass - - def assert_not_module_patched(self, cassandra_cluster): - pass - - def assert_not_module_double_patched(self, cassandra_cluster): - pass diff --git a/tests/contrib/celery/test_integration.py b/tests/contrib/celery/test_integration.py index 9646c0aceda..8a831e2c709 100644 --- a/tests/contrib/celery/test_integration.py +++ b/tests/contrib/celery/test_integration.py @@ -15,7 +15,6 @@ import ddtrace.internal.forksafe as forksafe from ddtrace.propagation.http import HTTPPropagator from ddtrace.trace import Context -from tests.opentracer.utils import init_tracer from ...utils import override_global_config from .base import CeleryBaseTestCase @@ -599,55 +598,6 @@ def fn_task(): assert run_trace[1].name == "test" assert run_trace[1].parent_id == run_trace[0].span_id - def test_fn_task_apply_async_ot(self): - """OpenTracing version of test_fn_task_apply_async.""" - ot_tracer = init_tracer("celery_svc", self.tracer) - - # it should execute a traced async task that has parameters - @self.app.task - def fn_task_parameters(user, force_logout=False): - return (user, force_logout) - - with ot_tracer.start_active_span("celery_op"): - t = fn_task_parameters.apply_async(args=["user"], kwargs={"force_logout": True}) - assert tuple(t.get(timeout=self.ASYNC_GET_TIMEOUT)) == ("user", True) - - ot_span = self.find_span(name="celery_op") - assert ot_span.parent_id is None - assert ot_span.name == "celery_op" - assert ot_span.service == "celery_svc" - - if self.ASYNC_USE_CELERY_FIXTURES: - async_span = self.find_span(name="celery.apply") - self.assert_is_measured(async_span) - assert async_span.error == 0 - - # confirm the parenting - assert async_span.parent_id == ot_span.span_id - assert async_span.name == "celery.apply" - assert async_span.resource == "tests.contrib.celery.test_integration.fn_task_parameters" - assert async_span.service == "celery-producer" - assert async_span.get_tag("celery.id") == t.task_id - assert async_span.get_tag("celery.action") == "apply_async" - assert async_span.get_tag("celery.routing_key") == "celery" - assert async_span.get_tag("component") == "celery" - assert async_span.get_tag("span.kind") == "producer" - assert async_span.get_tag("out.host") == "memory://" - - run_span = self.find_span(name="celery.run") - assert run_span.name == "celery.run" - assert run_span.parent_id is None - assert run_span.resource == "tests.contrib.celery.test_integration.fn_task_parameters" - assert run_span.service == "celery-worker" - assert run_span.get_tag("celery.id") == t.task_id - assert run_span.get_tag("celery.action") == "run" - assert run_span.get_tag("component") == "celery" - assert run_span.get_tag("span.kind") == "consumer" - - traces = self.pop_traces() - assert len(traces) == 2 - assert len(traces[0]) + len(traces[1]) == 3 - @pytest.mark.no_getattr_patch # this mark is added to prevent patching of getattr necessary for integration registry update # see: https://github.com/DataDog/dd-trace-py/pull/13215 diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index 7b58471c1d7..a10478fb143 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -36,7 +36,6 @@ from ddtrace.propagation.http import HTTP_HEADER_SAMPLING_PRIORITY from ddtrace.propagation.http import HTTP_HEADER_TRACE_ID from tests.conftest import DEFAULT_DDTRACE_SUBPROCESS_TEST_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.tracer.utils_inferred_spans.test_helpers import assert_web_and_inferred_aws_api_gateway_span_data from tests.utils import assert_dict_issuperset from tests.utils import override_config @@ -1952,38 +1951,6 @@ def test_template_name(test_spans): assert span.resource == "/my-template" -""" -OpenTracing tests -""" - - -@pytest.mark.django_db -def test_middleware_trace_request_ot(client, test_spans, tracer): - """OpenTracing version of test_middleware_trace_request.""" - ot_tracer = init_tracer("my_svc", tracer) - - # ensures that the internals are properly traced - with ot_tracer.start_active_span("ot_span"): - assert client.get("/users/").status_code == 200 - - # check for spans - spans = test_spans.get_spans() - ot_span = spans[0] - sp_request = spans[1] - - # confirm parenting - assert ot_span.parent_id is None - assert sp_request.parent_id == ot_span.span_id - - assert ot_span.resource == "ot_span" - assert ot_span.service == "my_svc" - - assert sp_request.get_tag("http.status_code") == "200" - assert sp_request.get_tag(http.URL) == "http://testserver/users/" - assert sp_request.get_tag("django.user.is_authenticated") == "False" - assert sp_request.get_tag("http.method") == "GET" - - def test_collecting_requests_handles_improperly_configured_error(client, test_spans): """ Since it's difficult to reproduce the ImproperlyConfigured error via django (server setup), will instead diff --git a/tests/contrib/falcon/test_suite.py b/tests/contrib/falcon/test_suite.py index 2cb912ee760..9771158e34d 100644 --- a/tests/contrib/falcon/test_suite.py +++ b/tests/contrib/falcon/test_suite.py @@ -3,7 +3,6 @@ from ddtrace.constants import USER_KEEP from ddtrace.contrib.internal.falcon.patch import FALCON_VERSION from ddtrace.ext import http as httpx -from tests.opentracer.utils import init_tracer from tests.tracer.utils_inferred_spans.test_helpers import assert_web_and_inferred_aws_api_gateway_span_data from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -225,37 +224,6 @@ def test_404_exception_no_stacktracer(self): assert span.get_tag("component") == "falcon" assert span.get_tag("span.kind") == "server" - def test_200_ot(self): - """OpenTracing version of test_200.""" - writer = self.tracer._span_aggregator.writer - ot_tracer = init_tracer("my_svc", self.tracer) - ot_tracer._dd_tracer._span_aggregator.writer = writer - ot_tracer._dd_tracer._recreate() - - with ot_tracer.start_active_span("ot_span"): - out = self.make_test_call("/200", expected_status_code=200) - assert out.content.decode("utf-8") == "Success" - - traces = self.tracer.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - ot_span, dd_span = traces[0] - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "my_svc" - assert ot_span.resource == "ot_span" - - assert_is_measured(dd_span) - assert dd_span.name == "falcon.request" - assert dd_span.service == self._service - assert dd_span.resource == "GET tests.contrib.falcon.app.resources.Resource200" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_tag(httpx.URL) == "http://falconframework.org/200" - assert dd_span.error == 0 - def test_falcon_request_hook(self): @config.falcon.hooks.on("request") def on_falcon_request(span, request, response): diff --git a/tests/contrib/flask_cache/test.py b/tests/contrib/flask_cache/test.py index 25ed861dbe2..6e23414eace 100644 --- a/tests/contrib/flask_cache/test.py +++ b/tests/contrib/flask_cache/test.py @@ -5,7 +5,6 @@ from ddtrace.contrib.internal.flask_cache.patch import get_traced_cache from ddtrace.ext import net from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_dict_issuperset from tests.utils import assert_is_measured @@ -317,44 +316,6 @@ def test_default_span_tags_memcached(self): self.assertEqual(span.get_tag(net.TARGET_HOST), "127.0.0.1") self.assertEqual(span.get_metric("network.destination.port"), self.TEST_MEMCACHED_PORT) - def test_simple_cache_get_ot(self): - """OpenTracing version of test_simple_cache_get.""" - ot_tracer = init_tracer("my_svc", self.tracer) - - # create the TracedCache instance for a Flask app - Cache = get_traced_cache(self.tracer, service=self.SERVICE) - app = Flask(__name__) - cache = Cache(app, config={"CACHE_TYPE": "simple"}) - - with ot_tracer.start_active_span("ot_span"): - cache.get("á_complex_operation") - - spans = self.get_spans() - self.assertEqual(len(spans), 2) - ot_span, dd_span = spans - - # confirm the parenting - self.assertIsNone(ot_span.parent_id) - self.assertEqual(dd_span.parent_id, ot_span.span_id) - - self.assertEqual(ot_span.resource, "ot_span") - self.assertEqual(ot_span.service, "my_svc") - - assert_is_measured(dd_span) - self.assertEqual(dd_span.service, self.SERVICE) - self.assertEqual(dd_span.resource, "get") - self.assertEqual(dd_span.name, "flask_cache.cmd") - self.assertEqual(dd_span.span_type, "cache") - self.assertEqual(dd_span.error, 0) - - expected_meta = { - "flask_cache.key": "á_complex_operation", - "flask_cache.backend": "simple", - "component": "flask_cache", - } - - assert_dict_issuperset(dd_span.get_tags(), expected_meta) - class TestFlaskCacheSchematization(TracerTestCase): TEST_REDIS_PORT = REDIS_CONFIG["port"] diff --git a/tests/contrib/futures/test_propagation.py b/tests/contrib/futures/test_propagation.py index 77a9e2f25a1..763052dda0c 100644 --- a/tests/contrib/futures/test_propagation.py +++ b/tests/contrib/futures/test_propagation.py @@ -6,7 +6,6 @@ from ddtrace.contrib.internal.futures.patch import patch from ddtrace.contrib.internal.futures.patch import unpatch -from tests.opentracer.utils import init_tracer from tests.utils import DummyTracer from tests.utils import TracerTestCase @@ -408,33 +407,6 @@ def fn(): assert spans[1].trace_id == spans[0].trace_id assert spans[1].parent_id == spans[0].span_id - def test_propagation_ot(self): - """OpenTracing version of test_propagation.""" - # it must propagate the tracing context if available - ot_tracer = init_tracer("my_svc", self.tracer) - - def fn(): - # an active context must be available - self.assertTrue(self.tracer.context_provider.active() is not None) - with self.tracer.trace("executor.thread"): - return 42 - - with self.override_global_tracer(): - with ot_tracer.start_active_span("main.thread"): - with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: - future = executor.submit(fn) - result = future.result() - # assert the right result - self.assertEqual(result, 42) - - # the trace must be completed - self.assert_span_count(2) - spans = self.get_spans() - assert spans[0].name == "main.thread" - assert spans[1].name == "executor.thread" - assert spans[1].trace_id == spans[0].trace_id - assert spans[1].parent_id == spans[0].span_id - @pytest.mark.skipif(sys.version_info > (3, 12), reason="Fails on 3.13") @pytest.mark.subprocess(ddtrace_run=True, timeout=5) diff --git a/tests/contrib/gevent/test_tracer.py b/tests/contrib/gevent/test_tracer.py index dc72ccc08ca..a7505d56f7d 100644 --- a/tests/contrib/gevent/test_tracer.py +++ b/tests/contrib/gevent/test_tracer.py @@ -2,7 +2,6 @@ import gevent import gevent.pool -from opentracing.scope_managers.gevent import GeventScopeManager import ddtrace from ddtrace.constants import ERROR_MSG @@ -11,7 +10,6 @@ from ddtrace.trace import Context from ddtrace.contrib.internal.gevent.patch import patch from ddtrace.contrib.internal.gevent.patch import unpatch -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from .utils import silence_errors @@ -356,34 +354,6 @@ def green_2(): spans = self.pop_spans() self._assert_spawn_multiple_greenlets(spans) - def test_trace_spawn_multiple_greenlets_multiple_traces_ot(self): - """OpenTracing version of the same test.""" - - ot_tracer = init_tracer("my_svc", self.tracer, scope_manager=GeventScopeManager()) - - def entrypoint(): - with ot_tracer.start_active_span("greenlet.main") as span: - span.resource = "base" - jobs = [gevent.spawn(green_1), gevent.spawn(green_2)] - gevent.joinall(jobs) - - def green_1(): - with self.tracer.trace("greenlet.worker1") as span: - span.set_tag("worker_id", "1") - gevent.sleep(0.01) - - # note that replacing the `tracer.trace` call here with the - # OpenTracing equivalent will cause the checks to fail - def green_2(): - with ot_tracer.start_active_span("greenlet.worker2") as scope: - scope.span.set_tag("worker_id", "2") - gevent.sleep(0.01) - - gevent.spawn(entrypoint).join() - - spans = self.pop_spans() - self._assert_spawn_multiple_greenlets(spans) - def test_ddtracerun(self): """ Regression test case for the following issue. diff --git a/tests/contrib/httplib/test_httplib.py b/tests/contrib/httplib/test_httplib.py index 7a2f4a07463..867afad7687 100644 --- a/tests/contrib/httplib/test_httplib.py +++ b/tests/contrib/httplib/test_httplib.py @@ -18,7 +18,6 @@ from ddtrace.ext import http from ddtrace.internal.constants import _HTTPLIB_NO_TRACE_REQUEST from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_span_http_status_code from tests.utils import override_global_tracer @@ -529,37 +528,6 @@ def test_urllib_request_opener(self): self.assertEqual(span.get_tag("span.kind"), "client") self.assertEqual(span.get_tag("out.host"), "localhost") - def test_httplib_request_get_request_ot(self): - """OpenTracing version of test with same name.""" - ot_tracer = init_tracer("my_svc", self.tracer) - - with ot_tracer.start_active_span("ot_span"): - conn = self.get_http_connection(SOCKET) - with contextlib.closing(conn): - conn.request("GET", "/status/200") - resp = conn.getresponse() - self.assertEqual(self.to_str(resp.read()), "") - self.assertEqual(resp.status, 200) - - spans = self.pop_spans() - self.assertEqual(len(spans), 2) - ot_span, dd_span = spans - - # confirm the parenting - self.assertEqual(ot_span.parent_id, None) - self.assertEqual(dd_span.parent_id, ot_span.span_id) - - self.assertEqual(ot_span.service, "my_svc") - self.assertEqual(ot_span.name, "ot_span") - - self.assert_is_not_measured(dd_span) - self.assertEqual(dd_span.span_type, "http") - self.assertEqual(dd_span.name, self.SPAN_NAME) - self.assertEqual(dd_span.error, 0) - assert dd_span.get_tag("http.method") == "GET" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_tag("http.url") == URL_200 - def test_httplib_bad_url(self): conn = self.get_http_connection("DNE", "80") with contextlib.closing(conn): diff --git a/tests/contrib/integration_registry/registry_update_helpers/integration_registry_manager.py b/tests/contrib/integration_registry/registry_update_helpers/integration_registry_manager.py index f5990c6c6c2..4e6659b6321 100644 --- a/tests/contrib/integration_registry/registry_update_helpers/integration_registry_manager.py +++ b/tests/contrib/integration_registry/registry_update_helpers/integration_registry_manager.py @@ -39,7 +39,7 @@ def _is_valid_patch_call(self, tb_string): """Checks if the patch call originated from ddtrace.contrib.internal/*/patch.py.""" # reverse the lines to check the most recent patch call first since some integrations call # other integrations patches: - # e.g. mongoengine calls pymongo's patch + # e.g. django calls postgres's patch return any( "ddtrace/contrib/internal" in line and "/patch.py" in line for line in reversed(tb_string.splitlines()) ) diff --git a/tests/contrib/mongoengine/__init__.py b/tests/contrib/mongoengine/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/contrib/mongoengine/test.py b/tests/contrib/mongoengine/test.py deleted file mode 100644 index d47c5a397e6..00000000000 --- a/tests/contrib/mongoengine/test.py +++ /dev/null @@ -1,415 +0,0 @@ -import time - -import mongoengine -import pymongo - -from ddtrace._trace.pin import Pin -from ddtrace.contrib.internal.mongoengine.patch import patch -from ddtrace.contrib.internal.mongoengine.patch import unpatch -from ddtrace.ext import mongo as mongox -from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer -from tests.utils import DummyTracer -from tests.utils import TracerTestCase -from tests.utils import assert_is_measured - -from ..config import MONGO_CONFIG - - -class Artist(mongoengine.Document): - first_name = mongoengine.StringField(max_length=50) - last_name = mongoengine.StringField(max_length=50) - - -class MongoEngineCore(object): - # Define the service at the class level, so that each test suite can use a different service - # and therefore catch any sneaky badly-unpatched stuff. - TEST_SERVICE = "deadbeef" - - def get_tracer_and_connect(self): - # implement me - pass - - def test_insert_update_delete_query(self): - tracer = self.get_tracer_and_connect() - - start = time.time() - Artist.drop_collection() - end = time.time() - - # ensure we get a drop collection span - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - - assert_is_measured(span) - assert span.resource == "drop artist" - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - _assert_timing(span, start, end) - - start = end - joni = Artist() - joni.first_name = "Joni" - joni.last_name = "Mitchell" - joni.save() - end = time.time() - - # ensure we get an insert span - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - assert_is_measured(span) - assert span.resource == "insert artist" - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - _assert_timing(span, start, end) - - # ensure full scans work - start = time.time() - artists = [a for a in Artist.objects] - end = time.time() - assert len(artists) == 1 - assert artists[0].first_name == "Joni" - assert artists[0].last_name == "Mitchell" - - # query names should be used in pymongo>3.1 - name = "find" if pymongo.version_tuple >= (3, 1, 0) else "query" - - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - assert_is_measured(span) - assert span.resource == "{} artist".format(name) - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - _assert_timing(span, start, end) - - # ensure filtered queries work - start = time.time() - artists = [a for a in Artist.objects(first_name="Joni")] - end = time.time() - assert len(artists) == 1 - joni = artists[0] - assert artists[0].first_name == "Joni" - assert artists[0].last_name == "Mitchell" - - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - assert_is_measured(span) - assert span.resource == '{} artist {{"first_name": "?"}}'.format(name) - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - _assert_timing(span, start, end) - - # ensure updates work - start = time.time() - joni.last_name = "From Saskatoon" - joni.save() - end = time.time() - - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - assert_is_measured(span) - assert span.resource == 'update artist {"_id": "?"}' - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - _assert_timing(span, start, end) - - # ensure deletes - start = time.time() - joni.delete() - end = time.time() - - spans = tracer.pop() - assert len(spans) == 2 - span = spans[1] - assert span.name == "pymongo.cmd" - assert_is_measured(span) - assert span.resource == 'delete artist {"_id": "?"}' - assert span.span_type == "mongodb" - assert span.service == self.TEST_SERVICE - assert span.get_tag("component") == "pymongo" - assert span.get_tag("span.kind") == "client" - assert span.get_tag("db.system") == "mongodb" - _assert_timing(span, start, end) - - def test_opentracing(self): - """Ensure the opentracer works with mongoengine.""" - tracer = self.get_tracer_and_connect() - ot_tracer = init_tracer("my_svc", tracer) - - with ot_tracer.start_active_span("ot_span"): - start = time.time() - Artist.drop_collection() - end = time.time() - - # ensure we get a drop collection span - spans = tracer.pop() - assert len(spans) == 3 - ot_span, dd_server_span, dd_cmd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_server_span.parent_id == ot_span.span_id - - assert ot_span.name == "ot_span" - assert ot_span.service == "my_svc" - - assert_is_measured(dd_cmd_span) - assert dd_cmd_span.resource == "drop artist" - assert dd_cmd_span.span_type == "mongodb" - assert dd_cmd_span.service == self.TEST_SERVICE - _assert_timing(dd_cmd_span, start, end) - - -class TestMongoEnginePatchConnectDefault(TracerTestCase, MongoEngineCore): - """Test suite with a global Pin for the connect function with the default configuration""" - - TEST_SERVICE = mongox.SERVICE - - def setUp(self): - patch() - - def tearDown(self): - unpatch() - # Disconnect and remove the client - mongoengine.connection.disconnect() - - def get_tracer_and_connect(self): - tracer = DummyTracer() - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - Pin.get_from(client)._clone(tracer=tracer).onto(client) - return tracer - - -class TestMongoEnginePatchConnectSchematization(TestMongoEnginePatchConnectDefault): - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) - def test_user_specified_service_default(self): - """ - : When a user specifies a service for the app - The mongoengine integration should not use it. - """ - from ddtrace import config - - assert config.service == "mysvc" - - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[1].name == "pymongo.cmd" - assert spans[1].service != "mysvc" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0", DD_SERVICE="mysvc")) - def test_user_specified_service_v0(self): - """ - v0: When a user specifies a service for the app - The mongoengine integration should not use it. - """ - from ddtrace import config - - assert config.service == "mysvc" - - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[1].name == "pymongo.cmd" - assert spans[1].service != "mysvc" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1", DD_SERVICE="mysvc")) - def test_user_specified_service_v1(self): - """ - In v1 of the span attribute schema, when a user specifies a service for the app - The mongoengine integration should use it as the default. - """ - from ddtrace import config - - assert config.service == "mysvc" - - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[1].name == "mongodb.query" - assert spans[1].service == "mysvc" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) - def test_unspecified_service_v0(self): - """ - In v0 of the span attribute schema, when there is no specified DD_SERVICE - The mongoengine integration should use None as the default. - """ - from ddtrace import config - - assert config.service is DEFAULT_SPAN_SERVICE_NAME - - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[0].service == "mongodb" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) - def test_unspecified_service_v1(self): - """ - In v1 of the span attribute schema, when there is no specified DD_SERVICE - The mongoengine integration should use DEFAULT_SPAN_SERVICE_NAME as the default. - """ - from ddtrace import config - - assert config.service == DEFAULT_SPAN_SERVICE_NAME - - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[0].service == DEFAULT_SPAN_SERVICE_NAME - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) - def test_span_name_v0_schema(self): - """ - When a user specifies a service for the app - The mongoengine integration should not use it. - """ - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[0].name == "pymongo.checkout" or spans[0].name == "pymongo.get_socket" - assert spans[1].name == "pymongo.cmd" - - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) - def test_span_name_v1_schema(self): - """ - When a user specifies a service for the app - The mongoengine integration should not use it. - """ - tracer = self.get_tracer_and_connect() - Artist.drop_collection() - - spans = tracer.pop() - assert len(spans) == 2 - assert spans[0].name == "pymongo.checkout" or spans[0].name == "pymongo.get_socket" - assert spans[1].name == "mongodb.query" - - -class TestMongoEnginePatchConnect(TestMongoEnginePatchConnectDefault): - """Test suite with a global Pin for the connect function with custom service""" - - TEST_SERVICE = "test-mongo-patch-connect" - - def get_tracer_and_connect(self): - tracer = TestMongoEnginePatchConnectDefault.get_tracer_and_connect(self) - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = tracer - pin.onto(mongoengine.connect) - mongoengine.connect(port=MONGO_CONFIG["port"]) - - return tracer - - -class TestMongoEnginePatchClientDefault(TracerTestCase, MongoEngineCore): - """Test suite with a Pin local to a specific client with default configuration""" - - TEST_SERVICE = mongox.SERVICE - - def setUp(self): - patch() - - def tearDown(self): - unpatch() - # Disconnect and remove the client - mongoengine.connection.disconnect() - - def get_tracer_and_connect(self): - tracer = DummyTracer() - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - Pin.get_from(client)._clone(tracer=tracer).onto(client) - - return tracer - - -class TestMongoEnginePatchClient(TestMongoEnginePatchClientDefault): - """Test suite with a Pin local to a specific client with custom service""" - - TEST_SERVICE = "test-mongo-patch-client" - - def get_tracer_and_connect(self): - tracer = DummyTracer() - # Set a connect-level service, to check that we properly override it - Pin(service="not-%s" % self.TEST_SERVICE).onto(mongoengine.connect) - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - pin = Pin(service=self.TEST_SERVICE) - pin._tracer = tracer - pin.onto(client) - - return tracer - - def test_patch_unpatch(self): - tracer = DummyTracer() - - # Test patch idempotence - patch() - patch() - - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - Pin.get_from(client)._clone(tracer=tracer).onto(client) - - Artist.drop_collection() - spans = tracer.pop() - assert spans, spans - assert len(spans) == 2 - - mongoengine.connection.disconnect() - tracer.pop() - - # Test unpatch - unpatch() - - mongoengine.connect(port=MONGO_CONFIG["port"]) - - Artist.drop_collection() - spans = tracer.pop() - assert not spans, spans - - # Disconnect so a new pymongo client can be created, - # connections are patched on instantiation - mongoengine.connection.disconnect() - # Test patch again - patch() - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - Pin.get_from(client)._clone(tracer=tracer).onto(client) - - Artist.drop_collection() - spans = tracer.pop() - assert spans, spans - assert len(spans) == 2 - - def test_multiple_connect_no_double_patching(self): - """Ensure we do not double patch client._topology - - Regression test for https://github.com/DataDog/dd-trace-py/issues/2474 - """ - client = mongoengine.connect(port=MONGO_CONFIG["port"]) - assert Pin.get_from(client) is Pin.get_from(client._topology) - client.close() - - -def _assert_timing(span, start, end): - assert start < span.start < end - assert span.duration < end - start diff --git a/tests/contrib/mongoengine/test_mongoengine_patch.py b/tests/contrib/mongoengine/test_mongoengine_patch.py deleted file mode 100644 index 6f219d1566e..00000000000 --- a/tests/contrib/mongoengine/test_mongoengine_patch.py +++ /dev/null @@ -1,31 +0,0 @@ -# This test script was automatically generated by the contrib-patch-tests.py -# script. If you want to make changes to it, you should make sure that you have -# removed the ``_generated`` suffix from the file name, to prevent the content -# from being overwritten by future re-generations. - -from ddtrace.contrib.internal.mongoengine.patch import get_version -from ddtrace.contrib.internal.mongoengine.patch import patch - - -try: - from ddtrace.contrib.internal.mongoengine.patch import unpatch -except ImportError: - unpatch = None -from tests.contrib.patch import PatchTestCase - - -class TestMongoenginePatch(PatchTestCase.Base): - __integration_name__ = "mongoengine" - __module_name__ = "mongoengine" - __patch_func__ = patch - __unpatch_func__ = unpatch - __get_version__ = get_version - - def assert_module_patched(self, mongoengine): - pass - - def assert_not_module_patched(self, mongoengine): - pass - - def assert_not_module_double_patched(self, mongoengine): - pass diff --git a/tests/contrib/mysql/test_mysql.py b/tests/contrib/mysql/test_mysql.py index a071731d470..edb7fed2076 100644 --- a/tests/contrib/mysql/test_mysql.py +++ b/tests/contrib/mysql/test_mysql.py @@ -6,7 +6,6 @@ from ddtrace.contrib.internal.mysql.patch import unpatch from tests.contrib import shared_tests from tests.contrib.config import MYSQL_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_dict_issuperset from tests.utils import assert_is_measured @@ -253,93 +252,6 @@ def test_query_proc(self): ) assert span.get_tag("sql.query") is None - def test_simple_query_ot(self): - """OpenTracing version of test_simple_query.""" - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 2 - - ot_span, dd_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "mysql" - assert dd_span.name == "mysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == 3306 - assert_dict_issuperset( - dd_span.get_tags(), - { - "out.host": "127.0.0.1", - "db.name": "test", - "db.system": "mysql", - "db.user": "test", - "component": "mysql", - "span.kind": "client", - }, - ) - - def test_simple_query_ot_fetchall(self): - """OpenTracing version of test_simple_query.""" - with self.override_config("mysql", dict(trace_fetch_methods=True)): - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 3 - - ot_span, dd_span, fetch_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "mysql" - assert dd_span.name == "mysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == 3306 - assert_dict_issuperset( - dd_span.get_tags(), - { - "out.host": "127.0.0.1", - "db.name": "test", - "db.system": "mysql", - "db.user": "test", - "component": "mysql", - "span.kind": "client", - }, - ) - - assert fetch_span.name == "mysql.query.fetchall" - def test_commit(self): conn, tracer = self._get_conn_tracer() conn.commit() diff --git a/tests/contrib/mysqldb/test_mysqldb.py b/tests/contrib/mysqldb/test_mysqldb.py index 344e42c46ad..82c99afd968 100644 --- a/tests/contrib/mysqldb/test_mysqldb.py +++ b/tests/contrib/mysqldb/test_mysqldb.py @@ -7,7 +7,6 @@ from ddtrace.contrib.internal.mysqldb.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from tests.contrib import shared_tests -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_dict_issuperset from tests.utils import assert_is_measured @@ -323,89 +322,6 @@ def test_query_proc(self): ) assert span.get_tag("sql.query") is None - def test_simple_query_ot(self): - """OpenTracing version of test_simple_query.""" - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "mysql" - assert dd_span.name == "mysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == 3306 - assert_dict_issuperset( - dd_span.get_tags(), - { - "out.host": "127.0.0.1", - "db.name": "test", - "db.system": "mysql", - "db.user": "test", - "component": "mysqldb", - "span.kind": "client", - }, - ) - - def test_simple_query_ot_fetchall(self): - """OpenTracing version of test_simple_query.""" - with self.override_config("mysqldb", dict(trace_fetch_methods=True)): - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 3 - ot_span, dd_span, fetch_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "mysql" - assert dd_span.name == "mysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == 3306 - assert_dict_issuperset( - dd_span.get_tags(), - { - "out.host": "127.0.0.1", - "db.name": "test", - "db.system": "mysql", - "db.user": "test", - "component": "mysqldb", - "span.kind": "client", - }, - ) - - assert fetch_span.name == "mysql.query.fetchall" - def test_commit(self): conn, tracer = self._get_conn_tracer() diff --git a/tests/contrib/psycopg/test_psycopg.py b/tests/contrib/psycopg/test_psycopg.py index 987890dbbd7..b433bcb68f3 100644 --- a/tests/contrib/psycopg/test_psycopg.py +++ b/tests/contrib/psycopg/test_psycopg.py @@ -14,7 +14,6 @@ from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from ddtrace.internal.utils.version import parse_version from tests.contrib.config import POSTGRES_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import snapshot @@ -142,47 +141,6 @@ def test_psycopg3_connection_with_string(self): Pin.get_from(conn)._clone(service="postgres", tracer=self.tracer).onto(conn) self.assert_conn_is_traced(conn, "postgres") - def test_opentracing_propagation(self): - # ensure OpenTracing plays well with our integration - query = """SELECT 'tracing'""" - - db = self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - cursor.execute(query) - rows = cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - (dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"),), - ) - assert_is_measured(self.get_spans()[1]) - self.reset() - - with self.override_config("psycopg", dict(trace_fetch_methods=True)): - db = self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - cursor.execute(query) - rows = cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - ( - dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"), - dict(name="postgres.query.fetchall", resource=query, service="postgres", error=0, span_type="sql"), - ), - ) - assert_is_measured(self.get_spans()[1]) - def test_cursor_ctx_manager(self): # ensure cursors work with context managers # https://github.com/DataDog/dd-trace-py/issues/228 diff --git a/tests/contrib/psycopg/test_psycopg_async.py b/tests/contrib/psycopg/test_psycopg_async.py index b4778e0693a..a21dc2d794c 100644 --- a/tests/contrib/psycopg/test_psycopg_async.py +++ b/tests/contrib/psycopg/test_psycopg_async.py @@ -10,7 +10,6 @@ from ddtrace.contrib.internal.psycopg.patch import unpatch from tests.contrib.asyncio.utils import AsyncioTestCase from tests.contrib.config import POSTGRES_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import assert_is_measured @@ -127,47 +126,6 @@ async def assert_conn_is_traced_async(self, db, service): self.assertIsNone(root.get_tag("sql.query")) self.reset() - async def test_opentracing_propagation(self): - # ensure OpenTracing plays well with our integration - query = """SELECT 'tracing'""" - - db = await self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - await cursor.execute(query) - rows = await cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - (dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"),), - ) - assert_is_measured(self.get_spans()[1]) - self.reset() - - with self.override_config("psycopg", dict(trace_fetch_methods=True)): - db = await self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - await cursor.execute(query) - rows = await cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - ( - dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"), - dict(name="postgres.query.fetchall", resource=query, service="postgres", error=0, span_type="sql"), - ), - ) - assert_is_measured(self.get_spans()[1]) - async def test_cursor_ctx_manager(self): # ensure cursors work with context managers # https://github.com/DataDog/dd-trace-py/issues/228 diff --git a/tests/contrib/psycopg2/test_psycopg.py b/tests/contrib/psycopg2/test_psycopg.py index 209de02c880..10051da0cff 100644 --- a/tests/contrib/psycopg2/test_psycopg.py +++ b/tests/contrib/psycopg2/test_psycopg.py @@ -13,7 +13,6 @@ from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from ddtrace.internal.utils.version import parse_version from tests.contrib.config import POSTGRES_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import snapshot @@ -148,47 +147,6 @@ def test_psycopg2_connection_with_string(self): Pin.get_from(conn)._clone(service="postgres", tracer=self.tracer).onto(conn) self.assert_conn_is_traced(conn, "postgres") - def test_opentracing_propagation(self): - # ensure OpenTracing plays well with our integration - query = """SELECT 'tracing'""" - - db = self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - cursor.execute(query) - rows = cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - (dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"),), - ) - assert_is_measured(self.get_spans()[1]) - self.reset() - - with self.override_config("psycopg", dict(trace_fetch_methods=True)): - db = self._get_conn() - ot_tracer = init_tracer("psycopg-svc", self.tracer) - - with ot_tracer.start_active_span("db.access"): - cursor = db.cursor() - cursor.execute(query) - rows = cursor.fetchall() - - self.assertEqual(rows, [("tracing",)]) - - self.assert_structure( - dict(name="db.access", service="psycopg-svc"), - ( - dict(name="postgres.query", resource=query, service="postgres", error=0, span_type="sql"), - dict(name="postgres.query.fetchall", resource=query, service="postgres", error=0, span_type="sql"), - ), - ) - assert_is_measured(self.get_spans()[1]) - @skipIf(PSYCOPG2_VERSION < (2, 5), "context manager not available in psycopg2==2.4") def test_cursor_ctx_manager(self): # ensure cursors work with context managers diff --git a/tests/contrib/pylibmc/test.py b/tests/contrib/pylibmc/test.py index da5823fc6b3..91242bbe871 100644 --- a/tests/contrib/pylibmc/test.py +++ b/tests/contrib/pylibmc/test.py @@ -12,7 +12,6 @@ from ddtrace.contrib.internal.pylibmc.patch import unpatch from ddtrace.ext import memcached from tests.contrib.config import MEMCACHED_CONFIG as cfg -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured @@ -78,33 +77,6 @@ def test_incr_decr(self): resources = sorted(s.resource for s in spans) assert expected_resources == resources - def test_incr_decr_ot(self): - """OpenTracing version of test_incr_decr.""" - client, tracer = self.get_client() - ot_tracer = init_tracer("memcached", tracer) - - start = time.time() - with ot_tracer.start_active_span("mc_ops"): - client.set("a", 1) - client.incr("a", 2) - client.decr("a", 1) - v = client.get("a") - assert v == 2 - end = time.time() - - # verify spans - spans = tracer.pop() - ot_span = spans[0] - - assert ot_span.name == "mc_ops" - - for s in spans[1:]: - assert s.parent_id == ot_span.span_id - self._verify_cache_span(s, start, end) - expected_resources = sorted(["get", "set", "incr", "decr"]) - resources = sorted(s.resource for s in spans[1:]) - assert expected_resources == resources - def test_clone(self): # ensure cloned connections are traced as well. client, tracer = self.get_client() diff --git a/tests/contrib/pymongo/test.py b/tests/contrib/pymongo/test.py index 236fa582910..ccabc218ce9 100644 --- a/tests/contrib/pymongo/test.py +++ b/tests/contrib/pymongo/test.py @@ -10,7 +10,6 @@ from ddtrace.contrib.internal.pymongo.patch import patch from ddtrace.contrib.internal.pymongo.patch import unpatch from ddtrace.ext import SpanTypes -from tests.opentracer.utils import init_tracer from tests.utils import DummyTracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured @@ -298,67 +297,6 @@ def test_insert_find(self): assert spans[-1].resource == 'find teams {"name": "?"}' assert spans[-1].get_tag("mongodb.query") == '{"name": "?"}' - def test_update_ot(self): - """OpenTracing version of test_update.""" - tracer, client = self.get_tracer_and_client() - ot_tracer = init_tracer("mongo_svc", tracer) - - with ot_tracer.start_active_span("mongo_op"): - db = client["testdb"] - db.drop_collection("songs") - input_songs = [ - {"name": "Powderfinger", "artist": "Neil"}, - {"name": "Harvest", "artist": "Neil"}, - {"name": "Suzanne", "artist": "Leonard"}, - {"name": "Partisan", "artist": "Leonard"}, - ] - db.songs.insert_many(input_songs) - result = db.songs.update_many( - {"artist": "Neil"}, - {"$set": {"artist": "Shakey"}}, - ) - - assert result.matched_count == 2 - assert result.modified_count == 2 - - # ensure all is traced. - spans = tracer.pop() - assert spans, spans - assert len(spans) == 7 - - ot_span = spans[0] - assert ot_span.parent_id is None - assert ot_span.name == "mongo_op" - assert ot_span.service == "mongo_svc" - - # remove pymongo.get_socket and pymongo.checkout spans - spans = [s for s in spans if s.name == "pymongo.cmd"] - assert len(spans) == 3 - for span in spans: - # ensure all the of the common metadata is set - assert_is_measured(span) - assert span.service == "pymongo" - assert span.span_type == "mongodb" - assert span.get_tag("component") == "pymongo" - assert span.get_tag("span.kind") == "client" - assert span.get_tag("db.system") == "mongodb" - assert span.get_tag("mongodb.collection") == "songs" - assert span.get_tag("mongodb.db") == "testdb" - assert span.get_tag("out.host") - assert span.get_metric("network.destination.port") - - expected_resources = set( - [ - "drop songs", - 'update songs {"artist": "?"}', - "insert songs", - "pymongo.get_socket", - "pymongo.checkout", - ] - ) - - assert {s.resource for s in spans[1:]}.issubset(expected_resources) - def test_rowcount(self): tracer, client = self.get_tracer_and_client() db = client["testdb"] diff --git a/tests/contrib/pymysql/test_pymysql.py b/tests/contrib/pymysql/test_pymysql.py index 762f55bed08..8fb5ef78621 100644 --- a/tests/contrib/pymysql/test_pymysql.py +++ b/tests/contrib/pymysql/test_pymysql.py @@ -6,7 +6,6 @@ from ddtrace.contrib.internal.pymysql.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from tests.contrib import shared_tests -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_dict_issuperset from tests.utils import assert_is_measured @@ -249,73 +248,6 @@ def test_query_proc(self): meta.update(self.DB_INFO) assert_dict_issuperset(span.get_tags(), meta) - def test_simple_query_ot(self): - """OpenTracing version of test_simple_query.""" - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "pymysql" - assert dd_span.name == "pymysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == MYSQL_CONFIG.get("port") - meta = {} - meta.update(self.DB_INFO) - assert_dict_issuperset(dd_span.get_tags(), meta) - - def test_simple_query_ot_fetchall(self): - """OpenTracing version of test_simple_query.""" - with self.override_config("pymysql", dict(trace_fetch_methods=True)): - conn, tracer = self._get_conn_tracer() - - ot_tracer = init_tracer("mysql_svc", tracer) - with ot_tracer.start_active_span("mysql_op"): - cursor = conn.cursor() - cursor.execute("SELECT 1") - rows = cursor.fetchall() - assert len(rows) == 1 - - spans = tracer.pop() - assert len(spans) == 3 - ot_span, dd_span, fetch_span = spans - - # confirm parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.service == "mysql_svc" - assert ot_span.name == "mysql_op" - - assert_is_measured(dd_span) - assert dd_span.service == "pymysql" - assert dd_span.name == "pymysql.query" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.get_metric("network.destination.port") == MYSQL_CONFIG.get("port") - meta = {} - meta.update(self.DB_INFO) - assert_dict_issuperset(dd_span.get_tags(), meta) - - assert fetch_span.name == "pymysql.query.fetchall" - def test_commit(self): conn, tracer = self._get_conn_tracer() diff --git a/tests/contrib/pyramid/utils.py b/tests/contrib/pyramid/utils.py index 3dec370d500..2f663258ac5 100644 --- a/tests/contrib/pyramid/utils.py +++ b/tests/contrib/pyramid/utils.py @@ -11,7 +11,6 @@ from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code -from ...opentracer.utils import init_tracer from .app import create_app @@ -273,33 +272,3 @@ def test_include_conflicts(self): self.app.get("/404", status=404) spans = self.pop_spans() assert len(spans) == 1 - - def test_200_ot(self): - """OpenTracing version of test_200.""" - ot_tracer = init_tracer("pyramid_svc", self.tracer) - - with ot_tracer.start_active_span("pyramid_get"): - res = self.app.get("/", status=200) - assert b"idx" in res.body - - spans = self.pop_spans() - assert len(spans) == 2 - - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "pyramid_get" - assert ot_span.service == "pyramid_svc" - - assert_is_measured(dd_span) - assert dd_span.service == "foobar" - assert dd_span.resource == "GET index" - assert dd_span.error == 0 - assert dd_span.span_type == "web" - assert dd_span.get_tag("http.method") == "GET" - assert_span_http_status_code(dd_span, 200) - assert dd_span.get_tag(http.URL) == "http://localhost/" - assert dd_span.get_tag("pyramid.route.name") == "index" diff --git a/tests/contrib/redis/test_redis.py b/tests/contrib/redis/test_redis.py index 31fe287fdf1..f2a42b83d19 100644 --- a/tests/contrib/redis/test_redis.py +++ b/tests/contrib/redis/test_redis.py @@ -4,12 +4,10 @@ import pytest import redis -import ddtrace from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.redis.patch import patch from ddtrace.contrib.internal.redis.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import DummyTracer from tests.utils import TracerTestCase from tests.utils import snapshot @@ -238,39 +236,6 @@ def test_patch_unpatch(self): assert spans, spans assert len(spans) == 1 - def test_opentracing(self): - """Ensure OpenTracing works with redis.""" - ot_tracer = init_tracer("redis_svc", self.tracer) - - with ot_tracer.start_active_span("redis_get"): - us = self.r.get("cheese") - assert us is None - - spans = self.get_spans() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "redis_get" - assert ot_span.service == "redis_svc" - - self.assert_is_measured(dd_span) - assert dd_span.service == "redis" - assert dd_span.name == "redis.command" - assert dd_span.span_type == "redis" - assert dd_span.error == 0 - assert dd_span.get_metric("out.redis_db") == 0 - assert dd_span.get_tag("out.host") == "localhost" - assert dd_span.get_tag("redis.raw_command") == "GET cheese" - assert dd_span.get_tag("component") == "redis" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.get_tag("db.system") == "redis" - assert dd_span.get_metric("redis.args_length") == 2 - assert dd_span.resource == "GET" - def test_redis_rowcount_all_keys_valid(self): self.r.set("key1", "value1") @@ -540,20 +505,6 @@ def test_patch_unpatch(self): assert spans, spans assert len(spans) == 1 - @snapshot() - def test_opentracing(self): - """Ensure OpenTracing works with redis.""" - writer = ddtrace.tracer._span_aggregator.writer - ot_tracer = init_tracer("redis_svc", ddtrace.tracer) - # FIXME: OpenTracing always overrides the hostname/port and creates a new - # writer so we have to reconfigure with the previous one - ddtrace.tracer._span_aggregator.writer = writer - ddtrace.tracer._recreate() - - with ot_tracer.start_active_span("redis_get"): - us = self.r.get("cheese") - assert us is None - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) @snapshot() def test_user_specified_service(self): diff --git a/tests/contrib/requests/test_requests.py b/tests/contrib/requests/test_requests.py index e1a8d2672d6..f7f7c24bc07 100644 --- a/tests/contrib/requests/test_requests.py +++ b/tests/contrib/requests/test_requests.py @@ -18,7 +18,6 @@ from ddtrace.contrib.internal.requests.patch import unpatch from ddtrace.ext import http from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -580,35 +579,6 @@ def test_global_config_service(self): spans = self.pop_spans() assert spans[0].service == "override" - def test_200_ot(self): - """OpenTracing version of test_200.""" - - ot_tracer = init_tracer("requests_svc", self.tracer) - - with ot_tracer.start_active_span("requests_get"): - out = self.session.get(URL_200) - assert out.status_code == 200 - - # validation - spans = self.pop_spans() - assert len(spans) == 2 - - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "requests_get" - assert ot_span.service == "requests_svc" - - assert_is_measured(dd_span) - assert dd_span.get_tag(http.METHOD) == "GET" - assert_span_http_status_code(dd_span, 200) - assert dd_span.error == 0 - assert dd_span.span_type == "http" - assert dd_span.resource == "GET /status/200" - def test_request_and_response_headers(self): # Disabled when not configured self.session.get(URL_200, headers={"my-header": "my_value"}) diff --git a/tests/contrib/snowflake/test_snowflake.py b/tests/contrib/snowflake/test_snowflake.py index f4995255b4c..67ce242b8e4 100644 --- a/tests/contrib/snowflake/test_snowflake.py +++ b/tests/contrib/snowflake/test_snowflake.py @@ -9,8 +9,6 @@ from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.snowflake.patch import patch from ddtrace.contrib.internal.snowflake.patch import unpatch -from ddtrace.trace import tracer -from tests.opentracer.utils import init_tracer from tests.utils import override_config from tests.utils import snapshot @@ -93,13 +91,6 @@ def client(): yield ctx -@contextlib.contextmanager -def ot_trace(): - ot = init_tracer("snowflake_svc", tracer) - with ot.start_active_span("snowflake_op"): - yield - - @snapshot() @req_mock.activate def test_snowflake_fetchone(client): @@ -224,72 +215,6 @@ def test_snowflake_executemany_insert(client): assert res.rowcount == 2 -@snapshot() -@req_mock.activate -def test_snowflake_ot_fetchone(client): - add_snowflake_query_response( - rowtype=["TEXT"], - rows=[("4.30.2",)], - ) - with ot_trace(): - with client.cursor() as cur: - res = cur.execute("select current_version();") - assert res == cur - assert cur.fetchone() == ("4.30.2",) - - -@snapshot() -@req_mock.activate -def test_snowflake_ot_fetchall(client): - add_snowflake_query_response( - rowtype=["TEXT"], - rows=[("4.30.2",)], - ) - with ot_trace(): - with client.cursor() as cur: - res = cur.execute("select current_version();") - assert res == cur - assert cur.fetchall() == [("4.30.2",)] - - -@snapshot() -@req_mock.activate -def test_snowflake_ot_fetchall_multiple_rows(client): - add_snowflake_query_response( - rowtype=["TEXT", "TEXT"], - rows=[("1a", "1b"), ("2a", "2b")], - ) - with ot_trace(): - with client.cursor() as cur: - res = cur.execute("select a, b from t;") - assert res == cur - assert cur.fetchall() == [ - ("1a", "1b"), - ("2a", "2b"), - ] - - -@snapshot() -@req_mock.activate -def test_snowflake_ot_executemany_insert(client): - add_snowflake_query_response( - rowtype=[], - rows=[], - total=2, - ) - with ot_trace(): - with client.cursor() as cur: - res = cur.executemany( - "insert into t (a, b) values (%s, %s);", - [ - ("1a", "1b"), - ("2a", "2b"), - ], - ) - assert res == cur - assert res.rowcount == 2 - - @pytest.mark.snapshot() @pytest.mark.parametrize( "service_schema", diff --git a/tests/contrib/sqlalchemy/mixins.py b/tests/contrib/sqlalchemy/mixins.py index 18b180db2d3..031c9ca3aea 100644 --- a/tests/contrib/sqlalchemy/mixins.py +++ b/tests/contrib/sqlalchemy/mixins.py @@ -9,7 +9,6 @@ from sqlalchemy.orm import sessionmaker from ddtrace.contrib.internal.sqlalchemy.engine import trace_engine -from tests.opentracer.utils import init_tracer Base = declarative_base() @@ -166,36 +165,3 @@ def test_engine_connect_execute(self): assert span.span_type == "sql" assert span.error == 0 assert span.duration > 0 - - def test_opentracing(self): - """Ensure that sqlalchemy works with the opentracer.""" - ot_tracer = init_tracer("sqlalch_svc", self.tracer) - - with ot_tracer.start_active_span("sqlalch_op"): - with self.connection() as conn: - rows = conn.execute(text("SELECT * FROM players")).fetchall() - assert len(rows) == 0 - - traces = self.pop_traces() - # trace composition - assert len(traces) == 1 - assert len(traces[0]) == 2 - ot_span, dd_span = traces[0] - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "sqlalch_op" - assert ot_span.service == "sqlalch_svc" - - # span fields - assert dd_span.name == "{}.query".format(self.VENDOR) - assert dd_span.service == self.SERVICE - assert dd_span.resource == "SELECT * FROM players" - assert dd_span.get_tag("sql.db") == self.SQL_DB - assert dd_span.get_tag("component") == "sqlalchemy" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.span_type == "sql" - assert dd_span.error == 0 - assert dd_span.duration > 0 diff --git a/tests/contrib/sqlite3/test_sqlite3.py b/tests/contrib/sqlite3/test_sqlite3.py index e4b12d7b4e8..de2b18f72b4 100644 --- a/tests/contrib/sqlite3/test_sqlite3.py +++ b/tests/contrib/sqlite3/test_sqlite3.py @@ -21,7 +21,6 @@ from ddtrace.contrib.internal.sqlite3.patch import patch from ddtrace.contrib.internal.sqlite3.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import assert_is_not_measured @@ -206,47 +205,6 @@ def test_sqlite_fetchmany_is_traced(self): self.assertIsNone(fetchmany_span.get_tag("sql.query")) self.assertEqual(fetchmany_span.get_tag("db.system"), "sqlite") - def test_sqlite_ot(self): - """Ensure sqlite works with the opentracer.""" - ot_tracer = init_tracer("sqlite_svc", self.tracer) - - # Ensure we can run a query and it's correctly traced - q = "select * from sqlite_master" - with ot_tracer.start_active_span("sqlite_op"): - db = sqlite3.connect(":memory:") - pin = Pin.get_from(db) - assert pin - pin._clone(tracer=self.tracer).onto(db) - cursor = db.execute(q) - rows = cursor.fetchall() - assert not rows - - self.assert_structure( - dict(name="sqlite_op", service="sqlite_svc"), - (dict(name="sqlite.query", service="sqlite", span_type="sql", resource=q, error=0),), - ) - assert_is_measured(self.get_spans()[1]) - self.reset() - - with self.override_config("sqlite", dict(trace_fetch_methods=True)): - with ot_tracer.start_active_span("sqlite_op"): - db = sqlite3.connect(":memory:") - pin = Pin.get_from(db) - assert pin - pin._clone(tracer=self.tracer).onto(db) - cursor = db.execute(q) - rows = cursor.fetchall() - assert not rows - - self.assert_structure( - dict(name="sqlite_op", service="sqlite_svc"), - ( - dict(name="sqlite.query", span_type="sql", resource=q, error=0), - dict(name="sqlite.query.fetchall", span_type="sql", resource=q, error=0), - ), - ) - assert_is_measured(self.get_spans()[1]) - def test_commit(self): connection = self._given_a_traced_connection(self.tracer) connection.commit() diff --git a/tests/contrib/suitespec.yml b/tests/contrib/suitespec.yml index 830cc5511b3..35e712500fa 100644 --- a/tests/contrib/suitespec.yml +++ b/tests/contrib/suitespec.yml @@ -31,9 +31,6 @@ components: bottle: - ddtrace/contrib/bottle.py - ddtrace/contrib/internal/bottle/* - cassandra: - - ddtrace/contrib/internal/cassandra/* - - ddtrace/ext/cassandra.py celery: - ddtrace/contrib/celery.py - ddtrace/contrib/internal/celery/* @@ -129,7 +126,6 @@ components: - ddtrace/contrib/internal/molten/* mongo: - ddtrace/contrib/internal/pymongo/* - - ddtrace/contrib/internal/mongoengine/* - ddtrace/ext/mongo.py mysql: - ddtrace/contrib/internal/mysql/* @@ -459,19 +455,6 @@ suites: - tests/contrib/bottle/* runner: riot snapshot: true - cassandra: - paths: - - '@bootstrap' - - '@core' - - '@contrib' - - '@tracing' - - '@cassandra' - - tests/contrib/cassandra/* - runner: riot - snapshot: true - parallelism: 2 - services: - - cassandra celery: env: DD_DISABLE_ERROR_RESPONSES: true @@ -898,18 +881,6 @@ suites: - tests/contrib/molten/* runner: riot snapshot: true - mongoengine: - paths: - - '@bootstrap' - - '@core' - - '@contrib' - - '@tracing' - - '@mongo' - - tests/contrib/mongoengine/* - runner: riot - snapshot: true - services: - - mongo mysqlpython: paths: - '@bootstrap' @@ -937,15 +908,6 @@ suites: - tests/snapshots/tests.opentelemetry.* runner: riot snapshot: true - opentracer: - parallelism: 1 - paths: - - '@bootstrap' - - '@core' - - '@tracing' - - '@opentracer' - - tests/opentracer/* - runner: riot protobuf: parallelism: 1 paths: diff --git a/tests/contrib/tornado/test_tornado_web.py b/tests/contrib/tornado/test_tornado_web.py index 642246aa244..cbb4d2c7785 100644 --- a/tests/contrib/tornado/test_tornado_web.py +++ b/tests/contrib/tornado/test_tornado_web.py @@ -1,6 +1,3 @@ -import pytest -import tornado - from ddtrace import config from ddtrace.constants import _ORIGIN_KEY from ddtrace.constants import _SAMPLING_PRIORITY_KEY @@ -8,7 +5,6 @@ from ddtrace.constants import USER_KEEP from ddtrace.ext import http from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.tracer.utils_inferred_spans.test_helpers import assert_web_and_inferred_aws_api_gateway_span_data from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -385,46 +381,6 @@ def test_propagation(self): assert request_span.get_tag("component") == "tornado" assert request_span.get_tag("span.kind") == "server" - # Opentracing support depends on new AsyncioScopeManager - # See: https://github.com/opentracing/opentracing-python/pull/118 - @pytest.mark.skipif( - tornado.version_info >= (5, 0), reason="Opentracing ScopeManager not available for Tornado >= 5" - ) - def test_success_handler_ot(self): - """OpenTracing version of test_success_handler.""" - from opentracing.scope_managers.tornado import TornadoScopeManager - - ot_tracer = init_tracer("tornado_svc", self.tracer, scope_manager=TornadoScopeManager()) - - with ot_tracer.start_active_span("tornado_op"): - response = self.fetch("/success/") - assert 200 == response.code - - traces = self.pop_traces() - assert 1 == len(traces) - assert 2 == len(traces[0]) - # dd_span will start and stop before the ot_span finishes - ot_span, dd_span = traces[0] - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "tornado_op" - assert ot_span.service == "tornado_svc" - - assert_is_measured(dd_span) - assert "tornado-web" == dd_span.service - assert "tornado.request" == dd_span.name - assert "web" == dd_span.span_type - assert "tests.contrib.tornado.web.app.SuccessHandler" == dd_span.resource - assert "GET" == dd_span.get_tag("http.method") - assert_span_http_status_code(dd_span, 200) - assert self.get_url("/success/") == dd_span.get_tag(http.URL) - assert 0 == dd_span.error - assert dd_span.get_tag("component") == "tornado" - assert dd_span.get_tag("span.kind") == "server" - class TestNoPropagationTornadoWebViaSetting(TornadoTestCase): """ diff --git a/tests/contrib/urllib3/test_urllib3.py b/tests/contrib/urllib3/test_urllib3.py index 01d3b87893c..c1a6434c0bc 100644 --- a/tests/contrib/urllib3/test_urllib3.py +++ b/tests/contrib/urllib3/test_urllib3.py @@ -14,7 +14,6 @@ from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from ddtrace.settings.asm import config as asm_config from tests.contrib.config import HTTPBIN_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import TracerTestCase from tests.utils import snapshot @@ -399,34 +398,6 @@ def test_split_by_domain_includes_port(self): assert s.error == 1 assert s.service == "httpbin.org:8000" - def test_200_ot(self): - """OpenTracing version of test_200.""" - - ot_tracer = init_tracer("urllib3_svc", self.tracer) - - with ot_tracer.start_active_span("urllib3_get"): - out = self.http.request("GET", URL_200) - assert out.status == 200 - - spans = self.pop_spans() - assert len(spans) == 2 - - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "urllib3_get" - assert ot_span.service == "urllib3_svc" - - assert dd_span.get_tag(http.METHOD) == "GET" - assert dd_span.get_tag(http.STATUS_CODE) == "200" - assert dd_span.get_tag("component") == "urllib3" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.error == 0 - assert dd_span.span_type == "http" - def test_request_and_response_headers(self): """Tests the headers are added as tag when the headers are whitelisted""" self.http.request("GET", URL_200, headers={"my-header": "my_value"}) diff --git a/tests/contrib/valkey/test_valkey.py b/tests/contrib/valkey/test_valkey.py index 867f435939e..447ae932771 100644 --- a/tests/contrib/valkey/test_valkey.py +++ b/tests/contrib/valkey/test_valkey.py @@ -4,12 +4,10 @@ import pytest import valkey -import ddtrace from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.valkey.patch import patch from ddtrace.contrib.internal.valkey.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME -from tests.opentracer.utils import init_tracer from tests.utils import DummyTracer from tests.utils import TracerTestCase from tests.utils import snapshot @@ -238,39 +236,6 @@ def test_patch_unpatch(self): assert spans, spans assert len(spans) == 1 - def test_opentracing(self): - """Ensure OpenTracing works with valkey.""" - ot_tracer = init_tracer("valkey_svc", self.tracer) - - with ot_tracer.start_active_span("valkey_get"): - us = self.r.get("cheese") - assert us is None - - spans = self.get_spans() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert ot_span.name == "valkey_get" - assert ot_span.service == "valkey_svc" - - self.assert_is_measured(dd_span) - assert dd_span.service == "valkey" - assert dd_span.name == "valkey.command" - assert dd_span.span_type == "valkey" - assert dd_span.error == 0 - assert dd_span.get_metric("out.valkey_db") == 0 - assert dd_span.get_tag("out.host") == "localhost" - assert dd_span.get_tag("valkey.raw_command") == "GET cheese" - assert dd_span.get_tag("component") == "valkey" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.get_tag("db.system") == "valkey" - assert dd_span.get_metric("valkey.args_length") == 2 - assert dd_span.resource == "GET" - def test_valkey_rowcount_all_keys_valid(self): self.r.set("key1", "value1") @@ -540,15 +505,6 @@ def test_patch_unpatch(self): assert spans, spans assert len(spans) == 1 - @snapshot() - def test_opentracing(self): - """Ensure OpenTracing works with valkey.""" - ot_tracer = init_tracer("valkey_svc", ddtrace.tracer) - - with ot_tracer.start_active_span("valkey_get"): - us = self.r.get("cheese") - assert us is None - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) @snapshot() def test_user_specified_service(self): diff --git a/tests/contrib/vertica/test_vertica.py b/tests/contrib/vertica/test_vertica.py index 1f3becdb8bf..223dce2982b 100644 --- a/tests/contrib/vertica/test_vertica.py +++ b/tests/contrib/vertica/test_vertica.py @@ -12,7 +12,6 @@ from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from ddtrace.settings._config import _deepmerge from tests.contrib.config import VERTICA_CONFIG -from tests.opentracer.utils import init_tracer from tests.utils import DummyTracer from tests.utils import TracerTestCase from tests.utils import assert_is_measured @@ -367,37 +366,6 @@ def test_copy(self): assert spans[1].name == "vertica.query" assert spans[1].resource == "COMMIT;" - def test_opentracing(self): - """Ensure OpenTracing works with vertica.""" - conn, cur = self.test_conn - - ot_tracer = init_tracer("vertica_svc", self.test_tracer) - - with ot_tracer.start_active_span("vertica_execute"): - cur.execute("INSERT INTO {} (a, b) VALUES (1, 'aa');".format(TEST_TABLE)) - conn.close() - - spans = self.test_tracer.pop() - assert len(spans) == 2 - ot_span, dd_span = spans - - # confirm the parenting - assert ot_span.parent_id is None - assert dd_span.parent_id == ot_span.span_id - - assert_is_measured(dd_span) - assert dd_span.service == "vertica" - assert dd_span.span_type == "sql" - assert dd_span.name == "vertica.query" - assert dd_span.get_metric("db.row_count") == -1 - query = "INSERT INTO test_table (a, b) VALUES (1, 'aa');" - assert dd_span.resource == query - assert dd_span.get_tag("out.host") == "127.0.0.1" - assert dd_span.get_tag("span.kind") == "client" - assert dd_span.get_metric("network.destination.port") == 5433 - assert dd_span.get_tag("db.system") == "vertica" - assert dd_span.get_tag("component") == "vertica" - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc"), use_pytest=True) @pytest.mark.usefixtures("test_tracer", "test_conn") def test_user_specified_service_default(self): diff --git a/tests/contrib/yaaredis/test_yaaredis.py b/tests/contrib/yaaredis/test_yaaredis.py index 472612f11ca..d3fa5743b70 100644 --- a/tests/contrib/yaaredis/test_yaaredis.py +++ b/tests/contrib/yaaredis/test_yaaredis.py @@ -9,7 +9,6 @@ from ddtrace.contrib.internal.yaaredis.patch import patch from ddtrace.contrib.internal.yaaredis.patch import unpatch from ddtrace.internal.compat import is_wrapted -from tests.opentracer.utils import init_tracer from tests.utils import override_config from ..config import REDIS_CONFIG @@ -149,18 +148,6 @@ async def test_service_name_config(tracer, test_spans, traced_yaaredis): assert test_spans.spans[0].service == service -@pytest.mark.asyncio -async def test_opentracing(tracer, snapshot_context, traced_yaaredis): - """Ensure OpenTracing works with redis.""" - - with snapshot_context(): - pin = Pin.get_from(traced_yaaredis) - ot_tracer = init_tracer("redis_svc", pin.tracer) - - with ot_tracer.start_active_span("redis_get"): - await traced_yaaredis.get("cheese") - - @pytest.mark.parametrize( "service_schema", [ diff --git a/tests/opentelemetry/test_span.py b/tests/opentelemetry/test_span.py index 3af064de795..61f9c6e0359 100644 --- a/tests/opentelemetry/test_span.py +++ b/tests/opentelemetry/test_span.py @@ -272,4 +272,3 @@ def test_otel_span_interoperability(oteltracer): otel_span_clone = Span(otel_span_og._ddspan) # Ensure all properties are consistent assert otel_span_clone.__dict__ == otel_span_og.__dict__ - assert otel_span_clone._ddspan._pprint() == otel_span_og._ddspan._pprint() diff --git a/tests/opentracer/__init__.py b/tests/opentracer/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/opentracer/conftest.py b/tests/opentracer/conftest.py deleted file mode 100644 index 09a4dad886c..00000000000 --- a/tests/opentracer/conftest.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -pytest local plugin used to automatically make the following fixtures -available for all tests in this directory - -https://docs.pytest.org/en/latest/writing_plugins.html#testing-plugins -""" -import pytest - -from ddtrace.opentracer import Tracer as OTTracer -from ddtrace.opentracer import set_global_tracer -from tests.utils import DummyTracer -from tests.utils import TracerSpanContainer - - -@pytest.fixture() -def ot_tracer_factory(): - """Fixture which returns an opentracer ready to use for testing.""" - - def make_ot_tracer(service_name="my_svc", config=None, scope_manager=None, context_provider=None): - config = config or {} - tracer = OTTracer(service_name=service_name, config=config, scope_manager=scope_manager) - - # similar to how we test the ddtracer, use a dummy tracer - dd_tracer = DummyTracer() - if context_provider: - dd_tracer.context_provider = context_provider - - # attach the dummy tracer to the opentracer - tracer._dd_tracer = dd_tracer - return tracer - - return make_ot_tracer - - -@pytest.fixture() -def ot_tracer(ot_tracer_factory): - """Fixture for a default opentracer.""" - return ot_tracer_factory() - - -@pytest.fixture -def test_spans(ot_tracer): - container = TracerSpanContainer(ot_tracer._dd_tracer) - yield container - container.reset() - - -@pytest.fixture() -def global_tracer(ot_tracer): - """A function similar to one OpenTracing users would write to initialize - their OpenTracing tracer. - """ - set_global_tracer(ot_tracer) - - return ot_tracer - - -@pytest.fixture() -def dd_tracer(ot_tracer): - return ot_tracer._dd_tracer diff --git a/tests/opentracer/core/__init__.py b/tests/opentracer/core/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/opentracer/core/test_dd_compatibility.py b/tests/opentracer/core/test_dd_compatibility.py deleted file mode 100644 index c68b5ca6d6c..00000000000 --- a/tests/opentracer/core/test_dd_compatibility.py +++ /dev/null @@ -1,180 +0,0 @@ -import opentracing -from opentracing import Format - -import ddtrace -from ddtrace.opentracer.span_context import SpanContext - - -class TestTracerCompatibility(object): - """Ensure that our opentracer produces results in the underlying ddtracer.""" - - def test_ottracer_uses_global_ddtracer(self): - """Ensure that the opentracer will by default use the global ddtracer - as its underlying Datadog tracer. - """ - tracer = ddtrace.opentracer.Tracer() - assert tracer._dd_tracer is ddtrace.tracer - - def test_ot_dd_global_tracers(self, global_tracer): - """Ensure our test function opentracer_init() prep""" - ot_tracer = global_tracer - dd_tracer = global_tracer._dd_tracer - - # check all the global references - assert ot_tracer is opentracing.tracer - assert ot_tracer._dd_tracer is dd_tracer - assert dd_tracer is ddtrace.tracer - - def test_ot_dd_nested_trace(self, ot_tracer, dd_tracer, test_spans): - """Ensure intertwined usage of the opentracer and ddtracer.""" - - with ot_tracer.start_span("my_ot_span") as ot_span: - with dd_tracer.trace("my_dd_span") as dd_span: - pass - spans = test_spans.pop() - assert len(spans) == 2 - - # confirm the ordering - assert spans[1] is ot_span._dd_span - assert spans[0] is dd_span - - # check the parenting - assert spans[0].parent_id is None - assert spans[1].parent_id is None - - def test_dd_ot_nested_trace(self, ot_tracer, dd_tracer, test_spans): - """Ensure intertwined usage of the opentracer and ddtracer.""" - with dd_tracer.trace("my_dd_span") as dd_span: - with ot_tracer.start_span("my_ot_span") as ot_span: - pass - spans = test_spans.pop() - assert len(spans) == 2 - - # confirm the ordering - assert spans[0] is dd_span - assert spans[1] is ot_span._dd_span - - # check the parenting - assert spans[0].parent_id is None - assert spans[1].parent_id is spans[0].span_id - - def test_ot_dd_ot_dd_nested_trace(self, ot_tracer, dd_tracer, test_spans): - """Ensure intertwined usage of the opentracer and ddtracer.""" - with ot_tracer.start_active_span("ot_span") as ot_scope: - with dd_tracer.trace("dd_span") as dd_span: - with ot_tracer.start_active_span("ot_span2") as ot_scope2: - with dd_tracer.trace("dd_span2") as dd_span2: - pass - - spans = test_spans.pop() - assert len(spans) == 4 - - spans = {span.name: span for span in spans} - assert spans["ot_span"] == ot_scope.span._dd_span - assert spans["dd_span"] == dd_span - assert spans["ot_span2"] == ot_scope2.span._dd_span - assert spans["dd_span2"] == dd_span2 - - # check the parenting - assert spans["ot_span"].parent_id is None - assert spans["dd_span"].parent_id is spans["ot_span"].span_id - assert spans["ot_span2"].parent_id is spans["dd_span"].span_id - assert spans["dd_span2"].parent_id is spans["ot_span2"].span_id - - def test_ot_ot_dd_ot_dd_nested_trace_active(self, ot_tracer, dd_tracer, test_spans): - """Ensure intertwined usage of the opentracer and ddtracer.""" - with ot_tracer.start_active_span("my_ot_span") as ot_scope: - with ot_tracer.start_active_span("my_ot_span") as ot_scope2: - with dd_tracer.trace("my_dd_span") as dd_span: - with ot_tracer.start_active_span("my_ot_span") as ot_scope3: - with dd_tracer.trace("my_dd_span") as dd_span2: - pass - - spans = test_spans.pop() - assert len(spans) == 5 - - # confirm the ordering - assert spans[0] is ot_scope.span._dd_span - assert spans[1] is ot_scope2.span._dd_span - assert spans[2] is dd_span - assert spans[3] is ot_scope3.span._dd_span - assert spans[4] is dd_span2 - - # check the parenting - assert spans[0].parent_id is None - assert spans[1].parent_id == spans[0].span_id - assert spans[2].parent_id == spans[1].span_id - assert spans[3].parent_id == spans[2].span_id - assert spans[4].parent_id == spans[3].span_id - - def test_consecutive_trace(self, ot_tracer, dd_tracer, test_spans): - """Ensure consecutive usage of the opentracer and ddtracer.""" - with ot_tracer.start_active_span("my_ot_span") as ot_scope: - pass - - with dd_tracer.trace("my_dd_span") as dd_span: - pass - - with ot_tracer.start_active_span("my_ot_span") as ot_scope2: - pass - - with dd_tracer.trace("my_dd_span") as dd_span2: - pass - - spans = test_spans.pop() - assert len(spans) == 4 - - # confirm the ordering - assert spans[0] is ot_scope.span._dd_span - assert spans[1] is dd_span - assert spans[2] is ot_scope2.span._dd_span - assert spans[3] is dd_span2 - - # check the parenting - assert spans[0].parent_id is None - assert spans[1].parent_id is None - assert spans[2].parent_id is None - assert spans[3].parent_id is None - - def test_ddtrace_wrapped_fn(self, ot_tracer, dd_tracer, test_spans): - """Ensure ddtrace wrapped functions work with the opentracer""" - - @dd_tracer.wrap() - def fn(): - with ot_tracer.start_span("ot_span_inner"): - pass - - with ot_tracer.start_active_span("ot_span_outer"): - fn() - - spans = test_spans.pop() - assert len(spans) == 3 - - # confirm the ordering - assert spans[0].name == "ot_span_outer" - assert spans[1].name == "tests.opentracer.core.test_dd_compatibility.fn" - assert spans[2].name == "ot_span_inner" - - # check the parenting - assert spans[0].parent_id is None - assert spans[1].parent_id is spans[0].span_id - assert spans[2].parent_id is spans[1].span_id - - def test_distributed_trace_propagation(self, ot_tracer, dd_tracer, test_spans): - """Ensure that a propagated span context is properly activated.""" - span_ctx = SpanContext(trace_id=123, span_id=456) - carrier = {} - ot_tracer.inject(span_ctx, Format.HTTP_HEADERS, carrier) - - # extract should activate the span so that a subsequent start_span - # will inherit from the propagated span context - ot_tracer.extract(Format.HTTP_HEADERS, carrier) - - with dd_tracer.trace("test") as span: - pass - - assert span.parent_id == 456 - assert span.trace_id == 123 - - spans = test_spans.pop() - assert len(spans) == 1 diff --git a/tests/opentracer/core/test_span.py b/tests/opentracer/core/test_span.py deleted file mode 100644 index ea2fc3bbbc1..00000000000 --- a/tests/opentracer/core/test_span.py +++ /dev/null @@ -1,163 +0,0 @@ -import pytest - -from ddtrace.opentracer.span import Span -from tests.utils import DummyTracer - - -@pytest.fixture -def nop_tracer(): - from ddtrace.opentracer import Tracer - - tracer = Tracer(service_name="mysvc", config={}) - # use the same test tracer used by the primary tests - tracer._tracer = DummyTracer() - return tracer - - -@pytest.fixture -def nop_span_ctx(): - from ddtrace.constants import AUTO_KEEP - from ddtrace.opentracer.span_context import SpanContext - - return SpanContext(sampling_priority=AUTO_KEEP) - - -@pytest.fixture -def nop_span(nop_tracer, nop_span_ctx): - return Span(nop_tracer, nop_span_ctx, "my_op_name") - - -class TestSpan(object): - """Test the Datadog OpenTracing Span implementation.""" - - def test_init(self, nop_tracer, nop_span_ctx): - """Very basic test for skeleton code""" - span = Span(nop_tracer, nop_span_ctx, "my_op_name") - assert not span.finished - - def test_tags(self, nop_span): - """Set a tag and get it back.""" - r = nop_span.set_tag("test", 23) - assert nop_span._get_metric("test") == 23 - assert r is nop_span - - def test_set_baggage(self, nop_span): - """Test setting baggage.""" - r = nop_span.set_baggage_item("test", 23) - assert r is nop_span - - r = nop_span.set_baggage_item("1", 1).set_baggage_item("2", 2) - assert r is nop_span - - def test_get_baggage(self, nop_span): - """Test setting and getting baggage.""" - # test a single item - nop_span.set_baggage_item("test", 23) - assert int(nop_span.get_baggage_item("test")) == 23 - - # test multiple items - nop_span.set_baggage_item("1", "1").set_baggage_item("2", 2) - assert int(nop_span.get_baggage_item("test")) == 23 - assert nop_span.get_baggage_item("1") == "1" - assert int(nop_span.get_baggage_item("2")) == 2 - - def test_log_kv(self, nop_span): - """Ensure logging values doesn't break anything.""" - # just log a bunch of values - nop_span.log_kv({"myval": 2}) - nop_span.log_kv({"myval2": 3}) - nop_span.log_kv({"myval3": 5}) - nop_span.log_kv({"myval": 2}) - - def test_log_dd_kv(self, nop_span): - """Ensure keys that can be handled by our impl. are indeed handled.""" - import traceback - - from ddtrace.constants import ERROR_MSG - from ddtrace.constants import ERROR_STACK - from ddtrace.constants import ERROR_TYPE - - stack_trace = str(traceback.format_stack()) - nop_span.log_kv( - { - "event": "error", - "error": 3, - "message": "my error message", - "stack": stack_trace, - } - ) - - # Ensure error flag is set... - assert nop_span._dd_span.error - # ...and that error tags are set with the correct key - assert nop_span._get_tag(ERROR_STACK) == stack_trace - assert nop_span._get_tag(ERROR_MSG) == "my error message" - assert nop_span._get_metric(ERROR_TYPE) == 3 - - def test_operation_name(self, nop_span): - """Sanity check for setting the operation name.""" - # just try setting the operation name - r = nop_span.set_operation_name("new_op_name") - assert nop_span._dd_span.name == "new_op_name" - assert r is nop_span - - def test_context_manager(self, nop_span): - """Test the span context manager.""" - import time - - assert not nop_span.finished - # run the context manager but since the span has not been added - # to the span context, we will not get any traces - with nop_span: - time.sleep(0.005) - - # span should be finished when the context manager exits - assert nop_span.finished - - # there should be no traces (see above comment) - spans = nop_span.tracer._tracer.pop() - assert len(spans) == 0 - - def test_immutable_span_context(self, nop_span): - """Ensure span contexts are immutable.""" - before_ctx = nop_span._context - nop_span.set_baggage_item("key", "value") - after_ctx = nop_span._context - # should be different contexts - assert before_ctx is not after_ctx - - -class TestSpanCompatibility(object): - """Ensure our opentracer spans features correspond to datadog span features.""" - - def test_set_tag(self, nop_span): - nop_span.set_tag("test", 2) - assert nop_span._get_metric("test") == 2 - - def test_tag_resource_name(self, nop_span): - nop_span.set_tag("resource.name", "myresource") - assert nop_span._dd_span.resource == "myresource" - - def test_tag_span_type(self, nop_span): - nop_span.set_tag("span.type", "db") - assert nop_span._dd_span.span_type == "db" - - def test_tag_service_name(self, nop_span): - nop_span.set_tag("service.name", "mysvc234") - assert nop_span._dd_span.service == "mysvc234" - - def test_tag_db_statement(self, nop_span): - nop_span.set_tag("db.statement", "SELECT * FROM USERS") - assert nop_span._dd_span.resource == "SELECT * FROM USERS" - - def test_tag_peer_hostname(self, nop_span): - nop_span.set_tag("peer.hostname", "peername") - assert nop_span._dd_span.get_tag("out.host") == "peername" - - def test_tag_peer_port(self, nop_span): - nop_span.set_tag("peer.port", 55555) - assert nop_span._get_metric("network.destination.port") == 55555 - - def test_tag_sampling_priority(self, nop_span): - nop_span.set_tag("sampling.priority", "2") - assert nop_span._dd_span.context.sampling_priority == "2" diff --git a/tests/opentracer/core/test_span_context.py b/tests/opentracer/core/test_span_context.py deleted file mode 100644 index 2c7038fe327..00000000000 --- a/tests/opentracer/core/test_span_context.py +++ /dev/null @@ -1,38 +0,0 @@ -from ddtrace.opentracer.span_context import SpanContext - - -class TestSpanContext(object): - def test_init(self): - """Make sure span context creation is fine.""" - span_ctx = SpanContext() - assert span_ctx - - def test_baggage(self): - """Ensure baggage passed is the resulting baggage of the span context.""" - baggage = { - "some": "stuff", - } - - span_ctx = SpanContext(baggage=baggage) - - assert span_ctx.baggage == baggage - - def test_with_baggage_item(self): - """Should allow immutable extension of new span contexts.""" - baggage = { - "1": 1, - } - - first_ctx = SpanContext(baggage=baggage) - - second_ctx = first_ctx.with_baggage_item("2", 2) - - assert "2" not in first_ctx.baggage - assert second_ctx.baggage is not first_ctx.baggage - - def test_span_context_immutable_baggage(self): - """Ensure that two different span contexts do not share baggage.""" - ctx1 = SpanContext() - ctx1.set_baggage_item("test", 3) - ctx2 = SpanContext() - assert "test" not in ctx2._baggage diff --git a/tests/opentracer/core/test_tracer.py b/tests/opentracer/core/test_tracer.py deleted file mode 100644 index 5d9f11ab74f..00000000000 --- a/tests/opentracer/core/test_tracer.py +++ /dev/null @@ -1,585 +0,0 @@ -import time - -import mock -import opentracing -from opentracing import Format -from opentracing import InvalidCarrierException -from opentracing import UnsupportedFormatException -from opentracing import child_of -import pytest - -import ddtrace -from ddtrace.constants import AUTO_KEEP -from ddtrace.opentracer import Tracer -from ddtrace.opentracer import set_global_tracer -from ddtrace.opentracer.span_context import SpanContext -from ddtrace.propagation.http import HTTP_HEADER_TRACE_ID -from ddtrace.settings.exceptions import ConfigException - - -class TestTracerConfig(object): - def test_config(self): - """Test the configuration of the tracer""" - config = {"enabled": True} - tracer = Tracer(service_name="myservice", config=config) - - assert tracer._service_name == "myservice" - assert tracer._dd_tracer.enabled is True - - def test_no_service_name(self): - """A service_name should be generated if one is not provided.""" - tracer = Tracer() - assert tracer._service_name in {"pytest.py", "pytest", "__main__.py"} - - def test_multiple_tracer_configs(self): - """Ensure that a tracer config is a copy of the passed config.""" - config = {"enabled": True} - - tracer1 = Tracer(service_name="serv1", config=config) - assert tracer1._service_name == "serv1" - - config["enabled"] = False - tracer2 = Tracer(service_name="serv2", config=config) - - # Ensure tracer1's config was not mutated - assert tracer1._service_name == "serv1" - assert tracer2._service_name == "serv2" - - def test_invalid_config_key(self): - """A config with an invalid key should raise a ConfigException.""" - - config = {"enabeld": False} # codespell:ignore - - # No debug flag should not raise an error - tracer = Tracer(service_name="mysvc", config=config) - - # With debug flag should raise an error - config["debug"] = True - with pytest.raises(ConfigException) as ce_info: - tracer = Tracer(config=config) - assert "enabeld" in str(ce_info) # codespell:ignore - assert tracer is not None - - # Test with multiple incorrect keys - config["setttings"] = {} - with pytest.raises(ConfigException) as ce_info: - tracer = Tracer(service_name="mysvc", config=config) - assert ["enabeld", "setttings"] in str(ce_info) # codespell:ignore - assert tracer is not None - - def test_global_tags(self): - """Global tags should be passed from the opentracer to the tracer.""" - config = { - "global_tags": { - "tag1": "value1", - "tag2": 2, - }, - } - - tracer = Tracer(service_name="mysvc", config=config) - with tracer.start_span("myop") as span: - # global tags should be attached to generated all datadog spans - assert span._dd_span.get_tag("tag1") == "value1" - assert span._dd_span.get_metric("tag2") == 2 - - with tracer.start_span("myop2") as span2: - assert span2._dd_span.get_tag("tag1") == "value1" - assert span2._dd_span.get_metric("tag2") == 2 - - -class TestTracer(object): - def test_start_span(self, ot_tracer, test_spans): - """Start and finish a span.""" - with ot_tracer.start_span("myop") as span: - pass - - # span should be finished when the context manager exits - assert span.finished - - spans = test_spans.get_spans() - assert len(spans) == 1 - - def test_start_span_references(self, ot_tracer, test_spans): - """Start a span using references.""" - - with ot_tracer.start_span("one", references=[child_of()]): - pass - - spans = test_spans.pop() - assert spans[0].parent_id is None - - root = ot_tracer.start_active_span("root") - # create a child using a parent reference that is not the context parent - with ot_tracer.start_active_span("one"): - with ot_tracer.start_active_span("two", references=[child_of(root.span)]): - pass - root.close() - - spans = test_spans.pop() - assert spans[1].parent_id == spans[0].span_id - assert spans[2].parent_id == spans[0].span_id - - def test_start_span_custom_start_time(self, ot_tracer): - """Start a span with a custom start time.""" - t = 100 - with mock.patch("ddtrace._trace.span.Time.time_ns") as time: - time.return_value = 102 * 1e9 - with ot_tracer.start_span("myop", start_time=t) as span: - pass - - assert span._dd_span.start == t - assert span._dd_span.duration == 2 - - def test_start_span_with_spancontext(self, ot_tracer, test_spans): - """Start and finish a span using a span context as the child_of - reference. - """ - with ot_tracer.start_span("myop") as span: - with ot_tracer.start_span("myop", child_of=span.context) as span2: - pass - - # span should be finished when the context manager exits - assert span.finished - assert span2.finished - - spans = test_spans.pop() - assert len(spans) == 2 - - # ensure proper parenting - assert spans[1].parent_id is spans[0].span_id - - def test_start_span_with_tags(self, ot_tracer): - """Create a span with initial tags.""" - tags = {"key": "value", "key2": "value2"} - with ot_tracer.start_span("myop", tags=tags) as span: - pass - - assert span._dd_span.get_tag("key") == "value" - assert span._dd_span.get_tag("key2") == "value2" - - def test_start_span_with_resource_name_tag(self, ot_tracer): - """Create a span with the tag to set the resource name""" - tags = {"resource.name": "value", "key2": "value2"} - with ot_tracer.start_span("myop", tags=tags) as span: - pass - - # Span resource name should be set to tag value, and should not get set as - # a tag on the underlying span. - assert span._dd_span.resource == "value" - assert span._dd_span.get_tag("resource.name") is None - - # Other tags are set as normal - assert span._dd_span.get_tag("key2") == "value2" - - def test_start_active_span_multi_child(self, ot_tracer, test_spans): - """Start and finish multiple child spans. - This should ensure that child spans can be created 2 levels deep. - """ - with ot_tracer.start_active_span("myfirstop") as scope1: - time.sleep(0.009) - with ot_tracer.start_active_span("mysecondop") as scope2: - time.sleep(0.007) - with ot_tracer.start_active_span("mythirdop") as scope3: - time.sleep(0.005) - - # spans should be finished when the context manager exits - assert scope1.span.finished - assert scope2.span.finished - assert scope3.span.finished - - spans = test_spans.pop() - - # check spans are captured in the trace - assert scope1.span._dd_span is spans[0] - assert scope2.span._dd_span is spans[1] - assert scope3.span._dd_span is spans[2] - - # ensure proper parenting - assert spans[1].parent_id is spans[0].span_id - assert spans[2].parent_id is spans[1].span_id - - # sanity check a lower bound on the durations - assert spans[0].duration >= 0.009 + 0.007 + 0.005 - assert spans[1].duration >= 0.007 + 0.005 - assert spans[2].duration >= 0.005 - - def test_start_active_span_multi_child_siblings(self, ot_tracer, test_spans): - """Start and finish multiple span at the same level. - This should test to ensure a parent can have multiple child spans at the - same level. - """ - with ot_tracer.start_active_span("myfirstop") as scope1: - time.sleep(0.009) - with ot_tracer.start_active_span("mysecondop") as scope2: - time.sleep(0.007) - with ot_tracer.start_active_span("mythirdop") as scope3: - time.sleep(0.005) - - # spans should be finished when the context manager exits - assert scope1.span.finished - assert scope2.span.finished - assert scope3.span.finished - - spans = test_spans.pop() - - # check spans are captured in the trace - assert scope1.span._dd_span is spans[0] - assert scope2.span._dd_span is spans[1] - assert scope3.span._dd_span is spans[2] - - # ensure proper parenting - assert spans[1].parent_id is spans[0].span_id - assert spans[2].parent_id is spans[0].span_id - - # sanity check a lower bound on the durations - assert spans[0].duration >= 0.009 + 0.007 + 0.005 - assert spans[1].duration >= 0.007 - assert spans[2].duration >= 0.005 - - def test_start_span_manual_child_of(self, ot_tracer, test_spans): - """Start spans without using a scope manager. - Spans should be created without parents since there will be no call - for the active span. - """ - root = ot_tracer.start_span("zero") - - with ot_tracer.start_span("one", child_of=root): - with ot_tracer.start_span("two", child_of=root): - with ot_tracer.start_span("three", child_of=root): - pass - root.finish() - - spans = test_spans.pop() - - assert spans[0].parent_id is None - # ensure each child span is a child of root - assert spans[1].parent_id is root._dd_span.span_id - assert spans[2].parent_id is root._dd_span.span_id - assert spans[3].parent_id is root._dd_span.span_id - assert spans[0].trace_id == spans[1].trace_id and spans[1].trace_id == spans[2].trace_id - - def test_start_span_no_active_span(self, ot_tracer, test_spans): - """Start spans without using a scope manager. - Spans should be created without parents since there will be no call - for the active span. - """ - with ot_tracer.start_span("one", ignore_active_span=True): - with ot_tracer.start_span("two", ignore_active_span=True): - pass - with ot_tracer.start_span("three", ignore_active_span=True): - pass - - spans = test_spans.pop() - - # ensure each span does not have a parent - assert spans[0].parent_id is None - assert spans[1].parent_id is None - assert spans[2].parent_id is None - # and that each span is a new trace - assert ( - spans[0].trace_id != spans[1].trace_id - and spans[1].trace_id != spans[2].trace_id - and spans[0].trace_id != spans[2].trace_id - ) - - def test_start_active_span_child_finish_after_parent(self, ot_tracer, test_spans): - """Start a child span and finish it after its parent.""" - span1 = ot_tracer.start_active_span("one").span - span2 = ot_tracer.start_active_span("two").span - span1.finish() - time.sleep(0.005) - span2.finish() - - spans = test_spans.pop() - assert len(spans) == 2 - assert spans[0].parent_id is None - assert spans[1].parent_id is span1._dd_span.span_id - assert spans[1].duration > spans[0].duration - - def test_start_span_multi_intertwined(self, ot_tracer, test_spans): - """Start multiple spans at the top level intertwined. - Alternate calling between two traces. - """ - import threading - - # synchronize threads with a threading event object - event = threading.Event() - - def trace_one(): - _id = 11 - with ot_tracer.start_active_span(str(_id)): - _id += 1 - with ot_tracer.start_active_span(str(_id)): - _id += 1 - with ot_tracer.start_active_span(str(_id)): - pass - event.set() - - def trace_two(): - _id = 21 - event.wait() - with ot_tracer.start_active_span(str(_id)): - _id += 1 - with ot_tracer.start_active_span(str(_id)): - _id += 1 - with ot_tracer.start_active_span(str(_id)): - pass - - # the ordering should be - # t1.span1/t2.span1, t2.span2, t1.span2, t1.span3, t2.span3 - t1 = threading.Thread(target=trace_one) - t2 = threading.Thread(target=trace_two) - - t1.start() - t2.start() - # wait for threads to finish - t1.join() - t2.join() - - spans = test_spans.pop() - - # trace_one will finish before trace_two so its spans should be written - # before the spans from trace_two, let's confirm this - assert spans[0].name == "11" - assert spans[1].name == "12" - assert spans[2].name == "13" - assert spans[3].name == "21" - assert spans[4].name == "22" - assert spans[5].name == "23" - - # next let's ensure that each span has the correct parent: - # trace_one - assert spans[0].parent_id is None - assert spans[1].parent_id is spans[0].span_id - assert spans[2].parent_id is spans[1].span_id - # trace_two - assert spans[3].parent_id is None - assert spans[4].parent_id is spans[3].span_id - assert spans[5].parent_id is spans[3].span_id - - # finally we should ensure that the trace_ids are reasonable - # trace_one - assert spans[0].trace_id == spans[1].trace_id and spans[1].trace_id == spans[2].trace_id - # traces should be independent - assert spans[2].trace_id != spans[3].trace_id - # trace_two - assert spans[3].trace_id == spans[4].trace_id and spans[4].trace_id == spans[5].trace_id - - def test_start_active_span(self, ot_tracer, test_spans): - with ot_tracer.start_active_span("one") as scope: - pass - - assert scope.span._dd_span.name == "one" - assert scope.span.finished - spans = test_spans.pop() - assert spans - - def test_start_active_span_finish_on_close(self, ot_tracer, test_spans): - with ot_tracer.start_active_span("one", finish_on_close=False) as scope: - pass - - assert scope.span._dd_span.name == "one" - assert not scope.span.finished - spans = test_spans.pop() - assert not spans - scope.span.finish() - - def test_start_active_span_nested(self, ot_tracer): - """Test the active span of multiple nested calls of start_active_span.""" - with ot_tracer.start_active_span("one") as outer_scope: - assert ot_tracer.active_span == outer_scope.span - with ot_tracer.start_active_span("two") as inner_scope: - assert ot_tracer.active_span == inner_scope.span - with ot_tracer.start_active_span("three") as innest_scope: # why isn't it innest? innermost so verbose - assert ot_tracer.active_span == innest_scope.span - with ot_tracer.start_active_span("two") as inner_scope: - assert ot_tracer.active_span == inner_scope.span - assert ot_tracer.active_span == outer_scope.span - assert ot_tracer.active_span is None - - def test_start_active_span_trace(self, ot_tracer, test_spans): - """Test the active span of multiple nested calls of start_active_span.""" - with ot_tracer.start_active_span("one") as outer_scope: - outer_scope.span.set_tag("outer", 2) - with ot_tracer.start_active_span("two") as inner_scope: - inner_scope.span.set_tag("inner", 3) - with ot_tracer.start_active_span("two") as inner_scope: - inner_scope.span.set_tag("inner", 3) - with ot_tracer.start_active_span("three") as innest_scope: - innest_scope.span.set_tag("innerest", 4) - - spans = test_spans.pop() - - assert spans[0].parent_id is None - assert spans[1].parent_id is spans[0].span_id - assert spans[2].parent_id is spans[0].span_id - assert spans[3].parent_id is spans[2].span_id - - def test_interleave(self, dd_tracer, ot_tracer, test_spans): - with ot_tracer.start_active_span("ot_root_1", ignore_active_span=True): - with dd_tracer.trace("dd_child"): - with ot_tracer.start_active_span("ot_child_1"): - pass - with ot_tracer.start_active_span("ot_child_2"): - pass - - spans = test_spans.pop() - assert len(spans) == 4 - assert spans[0].name == "ot_root_1" and spans[0].parent_id is None - assert spans[1].name == "dd_child" and spans[1].parent_id == spans[0].span_id - assert spans[2].name == "ot_child_1" and spans[2].parent_id == spans[1].span_id - assert spans[3].name == "ot_child_2" and spans[3].parent_id == spans[0].span_id - - def test_active_span(self, ot_tracer, test_spans): - with ot_tracer._dd_tracer.trace("dd") as span: - assert ot_tracer.active_span is not None - assert ot_tracer.active_span._dd_span is span - - -@pytest.fixture -def nop_span_ctx(): - return SpanContext(sampling_priority=AUTO_KEEP) - - -class TestTracerSpanContextPropagation(object): - """Test the injection and extraction of a span context from a tracer.""" - - def test_invalid_format(self, ot_tracer, nop_span_ctx): - """An invalid format should raise an UnsupportedFormatException.""" - # test inject - with pytest.raises(UnsupportedFormatException): - ot_tracer.inject(nop_span_ctx, None, {}) - - # test extract - with pytest.raises(UnsupportedFormatException): - ot_tracer.extract(None, {}) - - def test_inject_invalid_carrier(self, ot_tracer, nop_span_ctx): - """Only dicts should be supported as a carrier.""" - with pytest.raises(InvalidCarrierException): - ot_tracer.inject(nop_span_ctx, Format.HTTP_HEADERS, None) - - def test_extract_invalid_carrier(self, ot_tracer): - """Only dicts should be supported as a carrier.""" - with pytest.raises(InvalidCarrierException): - ot_tracer.extract(Format.HTTP_HEADERS, None) - - def test_http_headers_base(self, ot_tracer): - """extract should undo inject for http headers.""" - - span_ctx = SpanContext(trace_id=123, span_id=456) - carrier = {} - - ot_tracer.inject(span_ctx, Format.HTTP_HEADERS, carrier) - assert len(carrier.keys()) > 0 - - ext_span_ctx = ot_tracer.extract(Format.HTTP_HEADERS, carrier) - assert ext_span_ctx._dd_context.trace_id == 123 - assert ext_span_ctx._dd_context.span_id == 456 - - def test_http_headers_baggage(self, ot_tracer): - """extract should undo inject for http headers.""" - span_ctx = SpanContext(trace_id=123, span_id=456, baggage={"test": 4, "test2": "string"}) - carrier = {} - - ot_tracer.inject(span_ctx, Format.HTTP_HEADERS, carrier) - assert len(carrier.keys()) > 0 - - ext_span_ctx = ot_tracer.extract(Format.HTTP_HEADERS, carrier) - assert ext_span_ctx._dd_context.trace_id == 123 - assert ext_span_ctx._dd_context.span_id == 456 - assert ext_span_ctx.baggage == span_ctx.baggage - - def test_empty_propagated_context(self, ot_tracer): - """An empty propagated context should not raise a - SpanContextCorruptedException when extracted. - """ - carrier = {} - ot_tracer.extract(Format.HTTP_HEADERS, carrier) - - def test_text(self, ot_tracer): - """extract should undo inject for http headers""" - span_ctx = SpanContext(trace_id=123, span_id=456, baggage={"test": 4, "test2": "string"}) - carrier = {} - - ot_tracer.inject(span_ctx, Format.TEXT_MAP, carrier) - assert len(carrier.keys()) > 0 - - ext_span_ctx = ot_tracer.extract(Format.TEXT_MAP, carrier) - assert ext_span_ctx._dd_context.trace_id == 123 - assert ext_span_ctx._dd_context.span_id == 456 - assert ext_span_ctx.baggage == span_ctx.baggage - - def test_corrupted_propagated_context(self, ot_tracer): - """Corrupted context should raise a SpanContextCorruptedException.""" - span_ctx = SpanContext(trace_id=123, span_id=456, baggage={"test": 4, "test2": "string"}) - carrier = {} - - ot_tracer.inject(span_ctx, Format.TEXT_MAP, carrier) - assert len(carrier.keys()) > 0 - - # manually alter a key in the carrier baggage - del carrier[HTTP_HEADER_TRACE_ID] - corrupted_key = HTTP_HEADER_TRACE_ID[2:] - carrier[corrupted_key] = 123 - - ot_tracer.extract(Format.TEXT_MAP, carrier) - - def test_immutable_span_context(self, ot_tracer): - """Span contexts should be immutable.""" - with ot_tracer.start_span("root") as root: - ctx_before = root.context - root.set_baggage_item("test", 2) - assert ctx_before is not root.context - with ot_tracer.start_span("child") as level1: - with ot_tracer.start_span("child") as level2: - pass - assert root.context is not level1.context - assert level2.context is not level1.context - assert level2.context is not root.context - - def test_inherited_baggage(self, ot_tracer): - """Baggage should be inherited by child spans.""" - with ot_tracer.start_active_span("root") as root: - # this should be passed down to the child - root.span.set_baggage_item("root", 1) - root.span.set_baggage_item("root2", 1) - with ot_tracer.start_active_span("child") as level1: - level1.span.set_baggage_item("level1", 1) - with ot_tracer.start_active_span("child") as level2: - level2.span.set_baggage_item("level2", 1) - # ensure immutability - assert level1.span.context is not root.span.context - assert level2.span.context is not level1.span.context - - # level1 should have inherited the baggage of root - assert level1.span.get_baggage_item("root") - assert level1.span.get_baggage_item("root2") - - # level2 should have inherited the baggage of both level1 and level2 - assert level2.span.get_baggage_item("root") - assert level2.span.get_baggage_item("root2") - assert level2.span.get_baggage_item("level1") - assert level2.span.get_baggage_item("level2") - - -class TestTracerCompatibility(object): - """Ensure that our opentracer produces results in the underlying datadog tracer.""" - - def test_required_dd_fields(self): - """Ensure required fields needed for successful tracing are possessed - by the underlying datadog tracer. - """ - # a service name is required - tracer = Tracer("service") - with tracer.start_span("my_span") as span: - assert span._dd_span.service - - -def test_set_global_tracer(): - """Sanity check for set_global_tracer""" - my_tracer = Tracer("service") - set_global_tracer(my_tracer) - - assert opentracing.tracer is my_tracer - assert ddtrace.tracer is my_tracer._dd_tracer diff --git a/tests/opentracer/core/test_utils.py b/tests/opentracer/core/test_utils.py deleted file mode 100644 index 37c9e9dd305..00000000000 --- a/tests/opentracer/core/test_utils.py +++ /dev/null @@ -1,17 +0,0 @@ -from opentracing.scope_managers import ThreadLocalScopeManager -from opentracing.scope_managers.asyncio import AsyncioScopeManager - -import ddtrace -from ddtrace.opentracer.utils import get_context_provider_for_scope_manager - - -class TestOpentracerUtils(object): - def test_get_context_provider_for_scope_manager_thread(self): - scope_manager = ThreadLocalScopeManager() - ctx_prov = get_context_provider_for_scope_manager(scope_manager) - assert isinstance(ctx_prov, ddtrace._trace.provider.DefaultContextProvider) - - def test_get_context_provider_for_asyncio_scope_manager(self): - scope_manager = AsyncioScopeManager() - ctx_prov = get_context_provider_for_scope_manager(scope_manager) - assert isinstance(ctx_prov, ddtrace._trace.provider.DefaultContextProvider) diff --git a/tests/opentracer/test_tracer_asyncio.py b/tests/opentracer/test_tracer_asyncio.py deleted file mode 100644 index 35ece48c126..00000000000 --- a/tests/opentracer/test_tracer_asyncio.py +++ /dev/null @@ -1,143 +0,0 @@ -import asyncio - -import pytest - -from ddtrace.constants import ERROR_MSG - - -@pytest.mark.asyncio -def test_trace_coroutine(test_spans): - # it should use the task context when invoked in a coroutine - with test_spans.tracer.start_span("coroutine"): - pass - - traces = test_spans.pop_traces() - - assert len(traces) == 1 - assert len(traces[0]) == 1 - assert traces[0][0].name == "coroutine" - - -@pytest.mark.asyncio -async def test_trace_multiple_coroutines(ot_tracer, test_spans): - # if multiple coroutines have nested tracing, they must belong - # to the same trace - - async def coro(): - # another traced coroutine - with ot_tracer.start_active_span("coroutine_2"): - return 42 - - with ot_tracer.start_active_span("coroutine_1"): - value = await coro() - - # the coroutine has been called correctly - assert value == 42 - # a single trace has been properly reported - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - assert traces[0][0].name == "coroutine_1" - assert traces[0][1].name == "coroutine_2" - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id - - -@pytest.mark.asyncio -async def test_exception(ot_tracer, test_spans): - async def f1(): - with ot_tracer.start_span("f1"): - raise Exception("f1 error") - - with pytest.raises(Exception, match="f1 error"): - await f1() - - traces = test_spans.pop_traces() - assert len(traces) == 1 - spans = traces[0] - assert len(spans) == 1 - span = spans[0] - assert span.error == 1 - assert span.get_tag(ERROR_MSG) == "f1 error" - assert "Exception: f1 error" in span.get_tag("error.stack") - - -@pytest.mark.asyncio -async def test_trace_multiple_calls(ot_tracer, test_spans): - # create multiple futures so that we expect multiple - # traces instead of a single one (helper not used) - async def coro(): - # another traced coroutine - with ot_tracer.start_span("coroutine"): - await asyncio.sleep(0.01) - - futures = [asyncio.ensure_future(coro()) for x in range(10)] - for future in futures: - await future - - traces = test_spans.pop_traces() - - assert len(traces) == 10 - assert len(traces[0]) == 1 - assert traces[0][0].name == "coroutine" - - -@pytest.mark.asyncio -async def test_trace_multiple_coroutines_ot_dd(ot_tracer): - """ - Ensure we can trace from opentracer to ddtracer across asyncio - context switches. - """ - - # if multiple coroutines have nested tracing, they must belong - # to the same trace - async def coro(): - # another traced coroutine - with ot_tracer._dd_tracer.trace("coroutine_2"): - return 42 - - with ot_tracer.start_active_span("coroutine_1"): - value = await coro() - - # the coroutine has been called correctly - assert value == 42 - # a single trace has been properly reported - traces = ot_tracer._dd_tracer.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - assert traces[0][0].name == "coroutine_1" - assert traces[0][1].name == "coroutine_2" - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id - - -@pytest.mark.asyncio -async def test_trace_multiple_coroutines_dd_ot(ot_tracer): - """ - Ensure we can trace from ddtracer to opentracer across asyncio - context switches. - """ - - # if multiple coroutines have nested tracing, they must belong - # to the same trace - async def coro(): - # another traced coroutine - with ot_tracer.start_span("coroutine_2"): - return 42 - - with ot_tracer._dd_tracer.trace("coroutine_1"): - value = await coro() - - # the coroutine has been called correctly - assert value == 42 - # a single trace has been properly reported - traces = ot_tracer._dd_tracer.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - assert traces[0][0].name == "coroutine_1" - assert traces[0][1].name == "coroutine_2" - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id diff --git a/tests/opentracer/test_tracer_gevent.py b/tests/opentracer/test_tracer_gevent.py deleted file mode 100644 index 320b39ee997..00000000000 --- a/tests/opentracer/test_tracer_gevent.py +++ /dev/null @@ -1,193 +0,0 @@ -import gevent -from opentracing.scope_managers.gevent import GeventScopeManager -import pytest - -from ddtrace.contrib.internal.gevent.patch import patch -from ddtrace.contrib.internal.gevent.patch import unpatch - - -@pytest.fixture() -def ot_tracer(ot_tracer_factory): - """Fixture providing an opentracer configured for gevent usage.""" - # patch gevent - patch() - yield ot_tracer_factory("gevent_svc", {}, GeventScopeManager()) - # unpatch gevent - unpatch() - - -class TestTracerGevent(object): - """Converted Gevent tests for the regular tracer. - - Ensures that greenlets are properly traced when using - the opentracer. - """ - - def test_no_threading(self, ot_tracer): - with ot_tracer.start_span("span") as span: - span.set_tag("tag", "value") - - assert span.finished - - def test_greenlets(self, ot_tracer, test_spans): - def f(): - with ot_tracer.start_span("f") as span: - gevent.sleep(0.04) - span.set_tag("f", "yes") - - def g(): - with ot_tracer.start_span("g") as span: - gevent.sleep(0.03) - span.set_tag("g", "yes") - - with ot_tracer.start_active_span("root"): - gevent.joinall([gevent.spawn(f), gevent.spawn(g)]) - - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 3 - - def test_trace_greenlet(self, ot_tracer, test_spans): - # a greenlet can be traced using the trace API - def greenlet(): - with ot_tracer.start_span("greenlet"): - pass - - gevent.spawn(greenlet).join() - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 1 - assert traces[0][0].name == "greenlet" - - def test_trace_later_greenlet(self, ot_tracer, test_spans): - # a greenlet can be traced using the trace API - def greenlet(): - with ot_tracer.start_span("greenlet"): - pass - - gevent.spawn_later(0.01, greenlet).join() - traces = test_spans.pop_traces() - - assert len(traces) == 1 - assert len(traces[0]) == 1 - assert traces[0][0].name == "greenlet" - - def test_trace_concurrent_calls(self, ot_tracer, test_spans): - # create multiple futures so that we expect multiple - # traces instead of a single one - def greenlet(): - with ot_tracer.start_span("greenlet"): - gevent.sleep(0.01) - - jobs = [gevent.spawn(greenlet) for x in range(100)] - gevent.joinall(jobs) - - traces = test_spans.pop_traces() - - assert len(traces) == 100 - assert len(traces[0]) == 1 - assert traces[0][0].name == "greenlet" - - def test_trace_concurrent_spawn_later_calls(self, ot_tracer, test_spans): - # create multiple futures so that we expect multiple - # traces instead of a single one, even if greenlets - # are delayed - def greenlet(): - with ot_tracer.start_span("greenlet"): - gevent.sleep(0.01) - - jobs = [gevent.spawn_later(0.01, greenlet) for x in range(100)] - gevent.joinall(jobs) - - traces = test_spans.pop_traces() - assert len(traces) == 100 - assert len(traces[0]) == 1 - assert traces[0][0].name == "greenlet" - - -class TestTracerGeventCompatibility(object): - """Ensure the opentracer works in tandem with the ddtracer and gevent.""" - - def test_trace_spawn_multiple_greenlets_multiple_traces_ot_parent(self, ot_tracer, dd_tracer, test_spans): - """ - Copy of gevent test with the same name but testing with mixed usage of - the opentracer and datadog tracers. - - Uses an opentracer span as the parent span. - """ - - # multiple greenlets must be part of the same trace - def entrypoint(): - with ot_tracer.start_active_span("greenlet.main"): - jobs = [gevent.spawn(green_1), gevent.spawn(green_2)] - gevent.joinall(jobs) - - def green_1(): - with dd_tracer.trace("greenlet.worker") as span: - span.set_tag("worker_id", "1") - gevent.sleep(0.01) - - def green_2(): - with ot_tracer.start_span("greenlet.worker") as span: - span.set_tag("worker_id", "2") - gevent.sleep(0.01) - - gevent.spawn(entrypoint).join() - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 3 - parent_span = traces[0][0] - worker_1 = traces[0][1] - worker_2 = traces[0][2] - # check spans data and hierarchy - assert parent_span.name == "greenlet.main" - assert worker_1.get_tag("worker_id") == "1" - assert worker_1.name == "greenlet.worker" - assert worker_1.resource == "greenlet.worker" - assert worker_1.parent_id == parent_span.span_id - assert worker_2.get_tag("worker_id") == "2" - assert worker_2.name == "greenlet.worker" - assert worker_2.resource == "greenlet.worker" - assert worker_2.parent_id == parent_span.span_id - - def test_trace_spawn_multiple_greenlets_multiple_traces_dd_parent(self, ot_tracer, dd_tracer, test_spans): - """ - Copy of gevent test with the same name but testing with mixed usage of - the opentracer and datadog tracers. - - Uses an opentracer span as the parent span. - """ - - # multiple greenlets must be part of the same trace - def entrypoint(): - with dd_tracer.trace("greenlet.main"): - jobs = [gevent.spawn(green_1), gevent.spawn(green_2)] - gevent.joinall(jobs) - - def green_1(): - with ot_tracer.start_span("greenlet.worker") as span: - span.set_tag("worker_id", "1") - gevent.sleep(0.01) - - def green_2(): - with dd_tracer.trace("greenlet.worker") as span: - span.set_tag("worker_id", "2") - gevent.sleep(0.01) - - gevent.spawn(entrypoint).join() - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 3 - parent_span = traces[0][0] - worker_1 = traces[0][1] - worker_2 = traces[0][2] - # check spans data and hierarchy - assert parent_span.name == "greenlet.main" - assert worker_1.get_tag("worker_id") == "1" - assert worker_1.name == "greenlet.worker" - assert worker_1.resource == "greenlet.worker" - assert worker_1.parent_id == parent_span.span_id - assert worker_2.get_tag("worker_id") == "2" - assert worker_2.name == "greenlet.worker" - assert worker_2.resource == "greenlet.worker" - assert worker_2.parent_id == parent_span.span_id diff --git a/tests/opentracer/test_tracer_tornado.py b/tests/opentracer/test_tracer_tornado.py deleted file mode 100644 index d81541e0a52..00000000000 --- a/tests/opentracer/test_tracer_tornado.py +++ /dev/null @@ -1,30 +0,0 @@ -from opentracing.scope_managers.tornado import TornadoScopeManager -import pytest - - -@pytest.fixture() -def ot_tracer(ot_tracer_factory): - """Fixture providing an opentracer configured for tornado usage.""" - yield ot_tracer_factory("tornado_svc", {}, TornadoScopeManager()) - - -class TestTracerTornado(object): - """ - Since the ScopeManager is provided by OpenTracing we should simply test - whether it exists and works for a very simple use-case. - """ - - def test_sanity(self, ot_tracer, test_spans): - with ot_tracer.start_active_span("one"): - with ot_tracer.start_active_span("two"): - pass - - traces = test_spans.pop_traces() - assert len(traces) == 1 - assert len(traces[0]) == 2 - assert traces[0][0].name == "one" - assert traces[0][1].name == "two" - - # the parenting is correct - assert traces[0][0] == traces[0][1]._parent - assert traces[0][0].trace_id == traces[0][1].trace_id diff --git a/tests/opentracer/utils.py b/tests/opentracer/utils.py deleted file mode 100644 index 85b84865ad8..00000000000 --- a/tests/opentracer/utils.py +++ /dev/null @@ -1,11 +0,0 @@ -from ddtrace.opentracer import Tracer - - -def init_tracer(service_name, dd_tracer, scope_manager=None): - """A method that emulates what a user of OpenTracing would call to - initialize a Datadog opentracer. - - It accepts a Datadog tracer that should be the same one used for testing. - """ - ot_tracer = Tracer(service_name, scope_manager=scope_manager, _dd_tracer=dd_tracer) - return ot_tracer diff --git a/tests/suitespec.yml b/tests/suitespec.yml index 977f6685e79..8e24ecaf5d6 100644 --- a/tests/suitespec.yml +++ b/tests/suitespec.yml @@ -90,8 +90,6 @@ components: opentelemetry: - ddtrace/opentelemetry/* - ddtrace/internal/opentelemetry/* - opentracer: - - ddtrace/opentracer/* profiling: - ddtrace/profiling/* - ddtrace/internal/datadog/profiling/* diff --git a/tests/telemetry/test_telemetry_metrics_e2e.py b/tests/telemetry/test_telemetry_metrics_e2e.py index 8eed0b55426..03bf27b9682 100644 --- a/tests/telemetry/test_telemetry_metrics_e2e.py +++ b/tests/telemetry/test_telemetry_metrics_e2e.py @@ -141,69 +141,3 @@ def test_span_creation_and_finished_metrics_otel(test_agent_session, ddtrace_run assert metrics_sf[0]["metric"] == "spans_finished" assert metrics_sf[0]["tags"] == ["integration_name:otel"] assert metrics_sf[0]["points"][0][1] == 9 - - -def test_span_creation_and_finished_metrics_opentracing(test_agent_session, ddtrace_run_python_code_in_subprocess): - code = """ -from ddtrace.opentracer import Tracer - -ot = Tracer() -for _ in range(2): - with ot.start_span('span'): - pass -""" - env = os.environ.copy() - env["DD_TRACE_OTEL_ENABLED"] = "true" - env["_DD_INSTRUMENTATION_TELEMETRY_TESTS_FORCE_APP_STARTED"] = "true" - _, stderr, status, _ = ddtrace_run_python_code_in_subprocess(code, env=env) - assert status == 0, stderr - - metrics_sc = test_agent_session.get_metrics("spans_created") - assert len(metrics_sc) == 1 - assert metrics_sc[0]["metric"] == "spans_created" - assert metrics_sc[0]["tags"] == ["integration_name:opentracing"] - assert metrics_sc[0]["points"][0][1] == 2 - - metrics_sf = test_agent_session.get_metrics("spans_finished") - assert len(metrics_sf) == 1 - assert metrics_sf[0]["metric"] == "spans_finished" - assert metrics_sf[0]["tags"] == ["integration_name:opentracing"] - assert metrics_sf[0]["points"][0][1] == 2 - - -def test_span_creation_no_finish(test_agent_session, ddtrace_run_python_code_in_subprocess): - code = """ -import ddtrace -import opentelemetry.trace -from ddtrace import opentracer - -ddtracer = ddtrace.tracer -otel = opentelemetry.trace.get_tracer(__name__) -ot = opentracer.Tracer() - -# we must finish at least one span to enable sending telemetry to the agent -ddtracer.trace("first_span").finish() - -for _ in range(4): - ot.start_span('ot_span') - otel.start_span('otel_span') - ddtracer.trace("ddspan") -""" - env = os.environ.copy() - env["DD_TRACE_OTEL_ENABLED"] = "true" - env["_DD_INSTRUMENTATION_TELEMETRY_TESTS_FORCE_APP_STARTED"] = "true" - _, stderr, status, _ = ddtrace_run_python_code_in_subprocess(code, env=env) - assert status == 0, stderr - - metrics = test_agent_session.get_metrics("spans_created") - assert len(metrics) == 3 - - assert metrics[0]["metric"] == "spans_created" - assert metrics[0]["tags"] == ["integration_name:datadog"] - assert metrics[0]["points"][0][1] == 5 - assert metrics[1]["metric"] == "spans_created" - assert metrics[1]["tags"] == ["integration_name:opentracing"] - assert metrics[1]["points"][0][1] == 4 - assert metrics[2]["metric"] == "spans_created" - assert metrics[2]["tags"] == ["integration_name:otel"] - assert metrics[2]["points"][0][1] == 4 diff --git a/tests/tracer/test_correlation_log_context.py b/tests/tracer/test_correlation_log_context.py index abd82ad91a7..fa5f8b045f6 100644 --- a/tests/tracer/test_correlation_log_context.py +++ b/tests/tracer/test_correlation_log_context.py @@ -58,27 +58,6 @@ def test_get_log_correlation_trace_context(): }, dd_log_record -@pytest.mark.subprocess( - ddtrace_run=True, env={"DD_VERSION": "test-version", "DD_ENV": "test-env", "DD_SERVICE": "test-service"} -) -def test_get_log_correlation_context_opentracer(): - """Ensure expected DDLogRecord generated via get_correlation_log_record with an opentracing Tracer.""" - from ddtrace.internal.utils.formats import format_trace_id - from ddtrace.opentracer.tracer import Tracer as OT_Tracer - - ot_tracer = OT_Tracer(service_name="test-service") - with ot_tracer.start_active_span("operation") as scope: - dd_span = scope._span._dd_span - dd_log_record = ot_tracer.get_log_correlation_context() - assert dd_log_record == { - "dd.span_id": str(dd_span.span_id), - "dd.trace_id": format_trace_id(dd_span.trace_id), - "dd.service": "test-service", - "dd.env": "test-env", - "dd.version": "test-version", - }, dd_log_record - - @pytest.mark.subprocess() def test_get_log_correlation_context_no_active_span(): """Ensure empty DDLogRecord generated if no active span.""" diff --git a/tests/tracer/test_propagation.py b/tests/tracer/test_propagation.py index 9232d4c2f20..eee54604355 100644 --- a/tests/tracer/test_propagation.py +++ b/tests/tracer/test_propagation.py @@ -3515,22 +3515,6 @@ def test_http_propagator_baggage_extract(headers): assert context._baggage == {"key1": "val1", "key2": "val2", "foo": "bar", "x": "y"} -@pytest.mark.subprocess( - env=dict(DD_TRACE_PROPAGATION_HTTP_BAGGAGE_ENABLED="True"), - parametrize=dict(DD_TRACE_PROPAGATION_EXTRACT_FIRST=["True", "False"]), -) -def test_opentracer_propagator_baggage_extract(): - from ddtrace.propagation.http import HTTPPropagator - - headers = { - "x-datadog-trace-id": "1234", - "x-datadog-parent-id": "5678", - "http_ot_baggage_key1": "value1", - } - context = HTTPPropagator.extract(headers) - assert context._baggage == {"key1": "value1"} - - def test_baggage_span_tags_default(): headers = {"baggage": "user.id=123,correlation_id=abc,region=us-east"} context = HTTPPropagator.extract(headers) diff --git a/tests/tracer/test_span.py b/tests/tracer/test_span.py index a47391ef3da..fcfd753255f 100644 --- a/tests/tracer/test_span.py +++ b/tests/tracer/test_span.py @@ -10,7 +10,6 @@ from ddtrace._trace._span_link import SpanLink from ddtrace._trace._span_pointer import _SpanPointerDirection -from ddtrace._trace.context import Context from ddtrace.constants import _SPAN_MEASURED_KEY from ddtrace.constants import ENV_KEY from ddtrace.constants import ERROR_MSG @@ -866,52 +865,6 @@ def test_span_preconditions(arg): Span("test", **{arg: "foo"}) -def test_span_pprint(): - root = Span("test.span", service="s", resource="r", span_type=SpanTypes.WEB, context=Context(trace_id=1, span_id=2)) - root.set_tag("t", "v") - root.set_metric("m", 1.0) - root._add_event("message", {"importance": 10}, 16789898242) - root.set_link(trace_id=99, span_id=10, attributes={"link.name": "s1_to_s2", "link.kind": "scheduled_by"}) - root._add_span_pointer("test_kind", _SpanPointerDirection.DOWNSTREAM, "test_hash_123", {"extra": "attr"}) - - root.finish() - actual = root._pprint() - assert "name='test.span'" in actual - assert "service='s'" in actual - assert "resource='r'" in actual - assert "type='web'" in actual - assert "error=0" in actual - assert "tags={'t': 'v'}" in actual - assert "metrics={'m': 1.0}" in actual - assert "events=[SpanEvent(name='message', time=16789898242, attributes={'importance': 10})]" in actual - assert ( - "SpanLink(trace_id=99, span_id=10, attributes={'link.name': 's1_to_s2', 'link.kind': 'scheduled_by'}, " - "tracestate=None, flags=None, dropped_attributes=0)" - ) in actual - assert "SpanPointer(trace_id=0, span_id=0, kind=span-pointer" in actual - assert "direction=d, hash=test_hash_123" in actual - assert ( - f"context=Context(trace_id={root.trace_id}, span_id={root.span_id}, _meta={{}}, " - "_metrics={}, _span_links=[], _baggage={}, _is_remote=False)" - ) in actual - assert f"span_id={root.span_id}" in actual - assert f"trace_id={root.trace_id}" in actual - assert f"parent_id={root.parent_id}" in actual - assert f"start={root.start_ns}" in actual - assert f"duration={root.duration_ns}" in actual - assert f"end={root.start_ns + root.duration_ns}" in actual - - root = Span("test.span", service="s", resource="r", span_type=SpanTypes.WEB) - root.error = 1 - kv = {f"😌{i}": "😌" for i in range(100)} - root.set_tags(kv) - actual = root._pprint() - assert "duration=None" in actual - assert "end=None" in actual - assert "error=1" in actual - assert f"tags={kv}" in actual - - def test_manual_context_usage(): span1 = Span("span1") span2 = Span("span2", context=span1.context)