diff --git a/.circleci/config.templ.yml b/.circleci/config.templ.yml index 05af22df576..f5e4d63a24c 100644 --- a/.circleci/config.templ.yml +++ b/.circleci/config.templ.yml @@ -16,7 +16,7 @@ mongo_image: &mongo_image mongo:3.6@sha256:19c11a8f1064fd2bb713ef1270f79a742a184 httpbin_image: &httpbin_image kennethreitz/httpbin@sha256:2c7abc4803080c22928265744410173b6fea3b898872c01c5fd0f0f9df4a59fb vertica_image: &vertica_image sumitchawla/vertica:latest rabbitmq_image: &rabbitmq_image rabbitmq:3.7-alpine -testagent_image: &testagent_image ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.11.0 +testagent_image: &testagent_image ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.13.1 parameters: coverage: @@ -180,6 +180,28 @@ commands: path: test-results - store_artifacts: path: test-results + - run: + name: "Store Test Agent Supported Integrations Data" + command: | + if [[ -z "$(curl -s << parameters.trace_agent_url >>/test/integrations/tested_versions)" ]]; then + # No integrations were tested. Not saving any artifacts + echo "Response body is empty. Skipping saving integration artifacts." + else + # make temporary files to save response data to + response=$(mktemp) && headers=$(mktemp) + # create artifacts directory if it doesn't exist + [ -d "./artifacts" ] || mkdir -p "./artifacts" + # get tested integrations + curl -o "$response" -D "$headers" << parameters.trace_agent_url >>/test/integrations/tested_versions + # get filename representing the name of the tested integration from headers + filename=$(awk -F': ' '/file-name/{print $2}' "$headers" | tr -d '\r\n') + # copy data to final file and remove temp files + mv "$response" "artifacts/${filename}_supported_versions.csv" + rm "$headers" + fi + - store_artifacts: + path: artifacts + destination: supported-integrations - save_cache: key: lastsuccess-{{ .Environment.CIRCLE_BRANCH }}-<>-{{ .Environment.CIRCLE_NODE_INDEX }}-{{ epoch }} paths: @@ -472,6 +494,9 @@ jobs: test_logging: <<: *contrib_job + docker: + - image: *ddtrace_dev_image + - *testagent steps: - run_test: pattern: 'test_logging' @@ -584,6 +609,9 @@ jobs: dogpile_cache: <<: *contrib_job + docker: + - image: *ddtrace_dev_image + - *testagent steps: - run_test: pattern: 'dogpile_cache' @@ -770,6 +798,9 @@ jobs: pytest: <<: *contrib_job + docker: + - image: *ddtrace_dev_image + - *testagent steps: - run_test: pattern: 'pytest' diff --git a/ddtrace/contrib/elasticsearch/patch.py b/ddtrace/contrib/elasticsearch/patch.py index 9dd2082f79f..c6991f050e9 100644 --- a/ddtrace/contrib/elasticsearch/patch.py +++ b/ddtrace/contrib/elasticsearch/patch.py @@ -50,7 +50,9 @@ def _es_modules(): ) for module_name in module_names: try: - yield import_module(module_name) + module = import_module(module_name) + versions[module_name] = getattr(module, "__versionstr__", "") + yield module except ImportError: pass @@ -59,8 +61,6 @@ def _es_modules(): def get_version_tuple(elasticsearch): - if getattr(elasticsearch, "__name__", None): - versions[elasticsearch.__name__] = getattr(elasticsearch, "__versionstr__", "") return getattr(elasticsearch, "__version__", "") diff --git a/ddtrace/contrib/flask_login/patch.py b/ddtrace/contrib/flask_login/patch.py index 0c2d7ca3313..7b2474bf1f9 100644 --- a/ddtrace/contrib/flask_login/patch.py +++ b/ddtrace/contrib/flask_login/patch.py @@ -20,7 +20,7 @@ def get_version(): # type: () -> str - return "" + return flask_login.__version__ class _FlaskLoginUserInfoRetriever(_UserInfoRetriever): diff --git a/ddtrace/contrib/psycopg/patch.py b/ddtrace/contrib/psycopg/patch.py index 0ced7aa7503..f93388438e2 100644 --- a/ddtrace/contrib/psycopg/patch.py +++ b/ddtrace/contrib/psycopg/patch.py @@ -96,7 +96,9 @@ def _psycopg_modules(): ) for module_name in module_names: try: - yield import_module(module_name) + module = import_module(module_name) + PATCHED_VERSIONS[module_name] = getattr(module, "__version__", "") + yield module except ImportError: pass @@ -114,8 +116,6 @@ def _patch(psycopg_module): return psycopg_module._datadog_patch = True - PATCHED_VERSIONS[psycopg_module.__name__] = getattr(psycopg_module, "__version__", "") - Pin(_config=config.psycopg).onto(psycopg_module) if psycopg_module.__name__ == "psycopg2": diff --git a/ddtrace/contrib/sqlite3/__init__.py b/ddtrace/contrib/sqlite3/__init__.py index 3e6c259dd0b..c95b6d3fffa 100644 --- a/ddtrace/contrib/sqlite3/__init__.py +++ b/ddtrace/contrib/sqlite3/__init__.py @@ -53,8 +53,14 @@ cursor = db.cursor() cursor.execute("select * from users where id = 1") """ -from .patch import get_version -from .patch import patch +from ...internal.utils.importlib import require_modules -__all__ = ["patch", "get_version"] +required_modules = ["sqlite3"] + +with require_modules(required_modules) as missing_modules: + if not missing_modules: + from .patch import get_version + from .patch import patch + + __all__ = ["patch", "get_version"] diff --git a/ddtrace/contrib/unittest/__init__.py b/ddtrace/contrib/unittest/__init__.py index e0e6dc6f433..55e32c9c161 100644 --- a/ddtrace/contrib/unittest/__init__.py +++ b/ddtrace/contrib/unittest/__init__.py @@ -34,9 +34,15 @@ Default: ``True`` """ +from ...internal.utils.importlib import require_modules from .patch import get_version from .patch import patch from .patch import unpatch -__all__ = ["patch", "unpatch", "get_version"] +required_modules = ["unittest"] + +with require_modules(required_modules) as missing_modules: + if not missing_modules: + + __all__ = ["patch", "unpatch", "get_version"] diff --git a/docker-compose.yml b/docker-compose.yml index b3901ba6dcd..cf2b28895a0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -131,7 +131,7 @@ services: volumes: - ddagent:/tmp/ddagent:rw testagent: - image: ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.11.0 + image: ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.13.1 ports: - "127.0.0.1:9126:8126" volumes: diff --git a/riotfile.py b/riotfile.py index 41fd45b449f..3c64e335732 100644 --- a/riotfile.py +++ b/riotfile.py @@ -1205,7 +1205,7 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION): ), Venv( name="pyramid", - command="pytest {cmdargs} tests/contrib/pyramid/test_pyramid.py", + command="pytest {cmdargs} tests/contrib/pyramid", pkgs={ "requests": [latest], "webtest": [latest], diff --git a/scripts/contrib-patch-tests.py b/scripts/contrib-patch-tests.py index 5032ad639c4..cfefc113666 100644 --- a/scripts/contrib-patch-tests.py +++ b/scripts/contrib-patch-tests.py @@ -36,7 +36,7 @@ def generate_patch_test_source(contrib): if not required_modules_node: print( f"WARNING: failed to generate patch test for {contrib}," - " required_modules not found in ddtrace.contrib.{contrib}.__init__" + f" required_modules not found in ddtrace.contrib.{contrib}.__init__" ) return @@ -45,7 +45,7 @@ def generate_patch_test_source(contrib): if not required_modules: print( f"WARNING: failed to generate patch test for {contrib}," - " ddtrace.contrib.{contrib}.required_modules could not be parsed" + f" ddtrace.contrib.{contrib}.required_modules could not be parsed" ) return @@ -76,6 +76,7 @@ class Test{contrib.title()}Patch(PatchTestCase.Base): __module_name__ = "{module}" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, {module.replace(".", "_")}): pass @@ -85,11 +86,6 @@ def assert_not_module_patched(self, {module.replace(".", "_")}): def assert_not_module_double_patched(self, {module.replace(".", "_")}): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != '' """ ).lstrip() ) diff --git a/tests/contrib/aiobotocore/test_aiobotocore_patch_generated.py b/tests/contrib/aiobotocore/test_aiobotocore_patch.py similarity index 86% rename from tests/contrib/aiobotocore/test_aiobotocore_patch_generated.py rename to tests/contrib/aiobotocore/test_aiobotocore_patch.py index a5328ca61ac..7f56b2c90f4 100644 --- a/tests/contrib/aiobotocore/test_aiobotocore_patch_generated.py +++ b/tests/contrib/aiobotocore/test_aiobotocore_patch.py @@ -19,6 +19,7 @@ class TestAiobotocorePatch(PatchTestCase.Base): __module_name__ = "aiobotocore.client" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aiobotocore_client): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aiobotocore_client): def assert_not_module_double_patched(self, aiobotocore_client): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aiohttp/test_aiohttp_patch_generated.py b/tests/contrib/aiohttp/test_aiohttp_patch.py similarity index 85% rename from tests/contrib/aiohttp/test_aiohttp_patch_generated.py rename to tests/contrib/aiohttp/test_aiohttp_patch.py index c6f7c038963..e721bfc666c 100644 --- a/tests/contrib/aiohttp/test_aiohttp_patch_generated.py +++ b/tests/contrib/aiohttp/test_aiohttp_patch.py @@ -19,6 +19,7 @@ class TestAiohttpPatch(PatchTestCase.Base): __module_name__ = "aiohttp" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aiohttp): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aiohttp): def assert_not_module_double_patched(self, aiohttp): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch_generated.py b/tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch.py similarity index 86% rename from tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch_generated.py rename to tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch.py index 7619ecbaed6..e9dfc0d5e1b 100644 --- a/tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch_generated.py +++ b/tests/contrib/aiohttp_jinja2/test_aiohttp_jinja2_patch.py @@ -19,6 +19,7 @@ class TestAiohttp_Jinja2Patch(PatchTestCase.Base): __module_name__ = "aiohttp_jinja2" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aiohttp_jinja2): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aiohttp_jinja2): def assert_not_module_double_patched(self, aiohttp_jinja2): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aiomysql/test_aiomysql_patch_generated.py b/tests/contrib/aiomysql/test_aiomysql_patch.py similarity index 85% rename from tests/contrib/aiomysql/test_aiomysql_patch_generated.py rename to tests/contrib/aiomysql/test_aiomysql_patch.py index 5d9b07b2cd7..cbdb900d48f 100644 --- a/tests/contrib/aiomysql/test_aiomysql_patch_generated.py +++ b/tests/contrib/aiomysql/test_aiomysql_patch.py @@ -19,6 +19,7 @@ class TestAiomysqlPatch(PatchTestCase.Base): __module_name__ = "aiomysql" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aiomysql): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aiomysql): def assert_not_module_double_patched(self, aiomysql): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aiopg/test_aiopg_patch_generated.py b/tests/contrib/aiopg/test_aiopg_patch.py similarity index 85% rename from tests/contrib/aiopg/test_aiopg_patch_generated.py rename to tests/contrib/aiopg/test_aiopg_patch.py index c963e9b3df0..edbb57005cb 100644 --- a/tests/contrib/aiopg/test_aiopg_patch_generated.py +++ b/tests/contrib/aiopg/test_aiopg_patch.py @@ -19,6 +19,7 @@ class TestAiopgPatch(PatchTestCase.Base): __module_name__ = "aiopg" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aiopg): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aiopg): def assert_not_module_double_patched(self, aiopg): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aioredis/test_aioredis_patch_generated.py b/tests/contrib/aioredis/test_aioredis_patch.py similarity index 85% rename from tests/contrib/aioredis/test_aioredis_patch_generated.py rename to tests/contrib/aioredis/test_aioredis_patch.py index add2f7f17e5..2bcc5c3352e 100644 --- a/tests/contrib/aioredis/test_aioredis_patch_generated.py +++ b/tests/contrib/aioredis/test_aioredis_patch.py @@ -19,6 +19,7 @@ class TestAioredisPatch(PatchTestCase.Base): __module_name__ = "aioredis" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aioredis): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aioredis): def assert_not_module_double_patched(self, aioredis): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/algoliasearch/test_algoliasearch_patch_generated.py b/tests/contrib/algoliasearch/test_algoliasearch_patch.py similarity index 86% rename from tests/contrib/algoliasearch/test_algoliasearch_patch_generated.py rename to tests/contrib/algoliasearch/test_algoliasearch_patch.py index fe30e5c3670..324e1d37f78 100644 --- a/tests/contrib/algoliasearch/test_algoliasearch_patch_generated.py +++ b/tests/contrib/algoliasearch/test_algoliasearch_patch.py @@ -19,6 +19,7 @@ class TestAlgoliasearchPatch(PatchTestCase.Base): __module_name__ = "algoliasearch" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, algoliasearch): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, algoliasearch): def assert_not_module_double_patched(self, algoliasearch): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/aredis/test_aredis_patch_generated.py b/tests/contrib/aredis/test_aredis_patch.py similarity index 85% rename from tests/contrib/aredis/test_aredis_patch_generated.py rename to tests/contrib/aredis/test_aredis_patch.py index a5157491b28..f6d8c550883 100644 --- a/tests/contrib/aredis/test_aredis_patch_generated.py +++ b/tests/contrib/aredis/test_aredis_patch.py @@ -19,6 +19,7 @@ class TestAredisPatch(PatchTestCase.Base): __module_name__ = "aredis" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, aredis): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, aredis): def assert_not_module_double_patched(self, aredis): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/asyncpg/test_asyncpg_patch_generated.py b/tests/contrib/asyncpg/test_asyncpg_patch.py similarity index 85% rename from tests/contrib/asyncpg/test_asyncpg_patch_generated.py rename to tests/contrib/asyncpg/test_asyncpg_patch.py index 4a3700983e3..3e9a1dcac71 100644 --- a/tests/contrib/asyncpg/test_asyncpg_patch_generated.py +++ b/tests/contrib/asyncpg/test_asyncpg_patch.py @@ -19,6 +19,7 @@ class TestAsyncpgPatch(PatchTestCase.Base): __module_name__ = "asyncpg" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, asyncpg): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, asyncpg): def assert_not_module_double_patched(self, asyncpg): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/boto/test_boto_patch_generated.py b/tests/contrib/boto/test_boto_patch.py similarity index 85% rename from tests/contrib/boto/test_boto_patch_generated.py rename to tests/contrib/boto/test_boto_patch.py index 62634512b78..4dcc92ee184 100644 --- a/tests/contrib/boto/test_boto_patch_generated.py +++ b/tests/contrib/boto/test_boto_patch.py @@ -19,6 +19,7 @@ class TestBotoPatch(PatchTestCase.Base): __module_name__ = "boto.connection" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, boto_connection): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, boto_connection): def assert_not_module_double_patched(self, boto_connection): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/botocore/test_botocore_patch_generated.py b/tests/contrib/botocore/test_botocore_patch.py similarity index 86% rename from tests/contrib/botocore/test_botocore_patch_generated.py rename to tests/contrib/botocore/test_botocore_patch.py index 52850a53a89..abb24d96dc5 100644 --- a/tests/contrib/botocore/test_botocore_patch_generated.py +++ b/tests/contrib/botocore/test_botocore_patch.py @@ -19,6 +19,7 @@ class TestBotocorePatch(PatchTestCase.Base): __module_name__ = "botocore.client" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, botocore_client): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, botocore_client): def assert_not_module_double_patched(self, botocore_client): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/bottle/test_bottle_patch_generated.py b/tests/contrib/bottle/test_bottle_patch.py similarity index 85% rename from tests/contrib/bottle/test_bottle_patch_generated.py rename to tests/contrib/bottle/test_bottle_patch.py index 25781ce674f..1b255e1da2b 100644 --- a/tests/contrib/bottle/test_bottle_patch_generated.py +++ b/tests/contrib/bottle/test_bottle_patch.py @@ -19,6 +19,7 @@ class TestBottlePatch(PatchTestCase.Base): __module_name__ = "bottle" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, bottle): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, bottle): def assert_not_module_double_patched(self, bottle): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/cassandra/test_cassandra_patch_generated.py b/tests/contrib/cassandra/test_cassandra_patch.py similarity index 86% rename from tests/contrib/cassandra/test_cassandra_patch_generated.py rename to tests/contrib/cassandra/test_cassandra_patch.py index c1d1385278b..b1da5f99262 100644 --- a/tests/contrib/cassandra/test_cassandra_patch_generated.py +++ b/tests/contrib/cassandra/test_cassandra_patch.py @@ -19,6 +19,7 @@ class TestCassandraPatch(PatchTestCase.Base): __module_name__ = "cassandra.cluster" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, cassandra_cluster): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, cassandra_cluster): def assert_not_module_double_patched(self, cassandra_cluster): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/celery/test_patch.py b/tests/contrib/celery/test_patch.py index 4aebdde6cac..92380442dca 100644 --- a/tests/contrib/celery/test_patch.py +++ b/tests/contrib/celery/test_patch.py @@ -1,6 +1,7 @@ import unittest from ddtrace import Pin +from tests.contrib.patch import emit_integration_and_version_to_test_agent class CeleryPatchTest(unittest.TestCase): @@ -23,9 +24,11 @@ def test_patch_before_import(self): app = celery.Celery() assert Pin.get_from(app) is not None - def test_get_version(self): + def test_and_emit_get_version(self): from ddtrace.contrib.celery import get_version version = get_version() assert type(version) == str assert version != "" + + emit_integration_and_version_to_test_agent("celery", version) diff --git a/tests/contrib/cherrypy/test_middleware.py b/tests/contrib/cherrypy/test_middleware.py index 6a61a8c3878..e8569b54d49 100644 --- a/tests/contrib/cherrypy/test_middleware.py +++ b/tests/contrib/cherrypy/test_middleware.py @@ -17,6 +17,7 @@ from ddtrace.constants import SAMPLING_PRIORITY_KEY from ddtrace.contrib.cherrypy import TraceMiddleware from ddtrace.ext import http +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import TracerTestCase from tests.utils import assert_span_http_status_code from tests.utils import snapshot @@ -53,13 +54,15 @@ def setUp(self): distributed_tracing=True, ) - def test_get_version(self): + def test_and_emit_get_version(self): from ddtrace.contrib.cherrypy import get_version version = get_version() assert type(version) == str assert version != "" + emit_integration_and_version_to_test_agent("cherrypy", version) + def test_double_instrumentation(self): # ensure CherryPy is never instrumented twice when `ddtrace-run` # and `TraceMiddleware` are used together. `traced_app` MUST diff --git a/tests/contrib/consul/test_consul_patch_generated.py b/tests/contrib/consul/test_consul_patch.py similarity index 85% rename from tests/contrib/consul/test_consul_patch_generated.py rename to tests/contrib/consul/test_consul_patch.py index 8912af651c2..3ba449356e8 100644 --- a/tests/contrib/consul/test_consul_patch_generated.py +++ b/tests/contrib/consul/test_consul_patch.py @@ -19,6 +19,7 @@ class TestConsulPatch(PatchTestCase.Base): __module_name__ = "consul" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, consul): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, consul): def assert_not_module_double_patched(self, consul): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/django/test_django_patch.py b/tests/contrib/django/test_django_patch.py index 886599d0955..cec30ac004f 100644 --- a/tests/contrib/django/test_django_patch.py +++ b/tests/contrib/django/test_django_patch.py @@ -8,6 +8,7 @@ class TestDjangoPatch(PatchTestCase.Base): __module_name__ = "django" __patch_func__ = patch __unpatch_func__ = None + __get_version__ = get_version def assert_module_patched(self, django): import django.apps.registry @@ -50,8 +51,3 @@ def assert_not_module_double_patched(self, django): self.assert_not_double_wrapped(django.urls.path) self.assert_not_double_wrapped(django.urls.re_path) self.assert_not_double_wrapped(django.views.generic.base.View.as_view) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/dogpile_cache/test_dogpile_cache_patch_generated.py b/tests/contrib/dogpile_cache/test_dogpile_cache_patch.py similarity index 86% rename from tests/contrib/dogpile_cache/test_dogpile_cache_patch_generated.py rename to tests/contrib/dogpile_cache/test_dogpile_cache_patch.py index 7c0b5b37470..9c4de2a1985 100644 --- a/tests/contrib/dogpile_cache/test_dogpile_cache_patch_generated.py +++ b/tests/contrib/dogpile_cache/test_dogpile_cache_patch.py @@ -19,6 +19,7 @@ class TestDogpile_CachePatch(PatchTestCase.Base): __module_name__ = "dogpile.cache" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, dogpile_cache): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, dogpile_cache): def assert_not_module_double_patched(self, dogpile_cache): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/elasticsearch/test_elasticsearch.py b/tests/contrib/elasticsearch/test_elasticsearch.py index ece1f199890..3044fff0e78 100644 --- a/tests/contrib/elasticsearch/test_elasticsearch.py +++ b/tests/contrib/elasticsearch/test_elasticsearch.py @@ -6,10 +6,13 @@ from ddtrace import Pin from ddtrace import config from ddtrace.constants import ANALYTICS_SAMPLE_RATE_KEY +from ddtrace.contrib.elasticsearch.patch import get_version +from ddtrace.contrib.elasticsearch.patch import get_versions from ddtrace.contrib.elasticsearch.patch import patch from ddtrace.contrib.elasticsearch.patch import unpatch from ddtrace.ext import http from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import TracerTestCase from ..config import ELASTICSEARCH_CONFIG @@ -352,3 +355,13 @@ def test_large_body(self): self.reset() assert len(spans) == 1 assert len(spans[0].get_tag("elasticsearch.body")) < 25000 + + def test_and_emit_get_version(self): + version = get_version() + assert type(version) == str + assert version == "" + + versions = get_versions() + assert len(versions) > 0 + for module_name, v in versions.items(): + emit_integration_and_version_to_test_agent("elasticsearch", v, module_name=module_name) diff --git a/tests/contrib/falcon/test_falcon_patch_generated.py b/tests/contrib/falcon/test_falcon_patch.py similarity index 85% rename from tests/contrib/falcon/test_falcon_patch_generated.py rename to tests/contrib/falcon/test_falcon_patch.py index 533e8ab038c..013c5abc333 100644 --- a/tests/contrib/falcon/test_falcon_patch_generated.py +++ b/tests/contrib/falcon/test_falcon_patch.py @@ -19,6 +19,7 @@ class TestFalconPatch(PatchTestCase.Base): __module_name__ = "falcon" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, falcon): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, falcon): def assert_not_module_double_patched(self, falcon): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/fastapi/test_fastapi_patch.py b/tests/contrib/fastapi/test_fastapi_patch.py index 7bd7bc5d259..62cf0ab589e 100644 --- a/tests/contrib/fastapi/test_fastapi_patch.py +++ b/tests/contrib/fastapi/test_fastapi_patch.py @@ -9,6 +9,7 @@ class TestFastapiPatch(PatchTestCase.Base): __module_name__ = "fastapi" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, fastapi): self.assert_wrapped(fastapi.applications.FastAPI.build_middleware_stack) @@ -27,8 +28,3 @@ def assert_not_module_double_patched(self, fastapi): self.assert_not_double_wrapped(fastapi.routing.serialize_response) self.assert_not_double_wrapped(fastapi.routing.APIRoute.handle) self.assert_not_double_wrapped(fastapi.routing.Mount.handle) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/flask/test_flask_patch_generated.py b/tests/contrib/flask/test_flask_patch.py similarity index 85% rename from tests/contrib/flask/test_flask_patch_generated.py rename to tests/contrib/flask/test_flask_patch.py index 4d266dd64e4..af738988991 100644 --- a/tests/contrib/flask/test_flask_patch_generated.py +++ b/tests/contrib/flask/test_flask_patch.py @@ -19,6 +19,7 @@ class TestFlaskPatch(PatchTestCase.Base): __module_name__ = "flask" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, flask): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, flask): def assert_not_module_double_patched(self, flask): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/flask_login/test_flask_login_appsec.py b/tests/contrib/flask_login/test_flask_login_appsec.py index 088c783f5b8..108ac2e7ba5 100644 --- a/tests/contrib/flask_login/test_flask_login_appsec.py +++ b/tests/contrib/flask_login/test_flask_login_appsec.py @@ -14,6 +14,7 @@ from ddtrace.contrib.sqlite3.patch import patch from ddtrace.ext import user from tests.contrib.flask import BaseFlaskTestCase +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import override_global_config @@ -290,3 +291,12 @@ def login(): assert root_span.get_tag(APPSEC.USER_LOGIN_EVENT_PREFIX + ".success.auto.mode") == "safe" finally: unpatch_login() + + def test_and_emit_get_version(self): + from ddtrace.contrib.flask_login import get_version + + version = get_version() + assert type(version) == str + assert version != "" + + emit_integration_and_version_to_test_agent("flask_login", version) diff --git a/tests/contrib/futures/test_futures_patch_generated.py b/tests/contrib/futures/test_futures_patch.py similarity index 80% rename from tests/contrib/futures/test_futures_patch_generated.py rename to tests/contrib/futures/test_futures_patch.py index 4683830f218..fca6a316c00 100644 --- a/tests/contrib/futures/test_futures_patch_generated.py +++ b/tests/contrib/futures/test_futures_patch.py @@ -2,6 +2,8 @@ # 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.futures import get_version from ddtrace.contrib.futures.patch import patch @@ -17,6 +19,7 @@ class TestFuturesPatch(PatchTestCase.Base): __module_name__ = "concurrent.futures.thread" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, concurrent_futures): pass @@ -27,5 +30,7 @@ def assert_not_module_patched(self, concurrent_futures): def assert_not_module_double_patched(self, concurrent_futures): pass - def assert_module_implements_get_version(self): - pass + def test_and_emit_get_version(self): + version = get_version() + assert type(version) == str + assert version == "" diff --git a/tests/contrib/gevent/test_gevent_patch_generated.py b/tests/contrib/gevent/test_gevent_patch.py similarity index 85% rename from tests/contrib/gevent/test_gevent_patch_generated.py rename to tests/contrib/gevent/test_gevent_patch.py index b6bb04dc0c3..6013517bb2d 100644 --- a/tests/contrib/gevent/test_gevent_patch_generated.py +++ b/tests/contrib/gevent/test_gevent_patch.py @@ -19,6 +19,7 @@ class TestGeventPatch(PatchTestCase.Base): __module_name__ = "gevent" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, gevent): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, gevent): def assert_not_module_double_patched(self, gevent): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != '' diff --git a/tests/contrib/graphql/test_graphql_patch_generated.py b/tests/contrib/graphql/test_graphql_patch.py similarity index 85% rename from tests/contrib/graphql/test_graphql_patch_generated.py rename to tests/contrib/graphql/test_graphql_patch.py index 099db31e7b0..951e69998f3 100644 --- a/tests/contrib/graphql/test_graphql_patch_generated.py +++ b/tests/contrib/graphql/test_graphql_patch.py @@ -19,6 +19,7 @@ class TestGraphqlPatch(PatchTestCase.Base): __module_name__ = "graphql" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, graphql): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, graphql): def assert_not_module_double_patched(self, graphql): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/grpc/test_grpc_patch.py b/tests/contrib/grpc/test_grpc_patch.py index 497114259c3..805b6996a3c 100644 --- a/tests/contrib/grpc/test_grpc_patch.py +++ b/tests/contrib/grpc/test_grpc_patch.py @@ -8,6 +8,7 @@ class TestGRPCPatch(PatchTestCase.Base): __module_name__ = "grpc" __patch_func__ = patch __unpatch_func__ = None + __get_version__ = get_version def assert_module_patched(self, grpc): # Client Wrapping @@ -32,8 +33,3 @@ def assert_not_module_double_patched(self, grpc): self.assert_not_double_wrapped(grpc.intercept_channel) # Server Wrapping self.assert_not_double_wrapped(grpc.server) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/httplib/test_httplib_patch.py b/tests/contrib/httplib/test_httplib_patch.py index fb3612fc707..3b29a502a17 100644 --- a/tests/contrib/httplib/test_httplib_patch.py +++ b/tests/contrib/httplib/test_httplib_patch.py @@ -1,3 +1,4 @@ +from ddtrace.contrib.httplib.patch import get_version from ddtrace.contrib.httplib.patch import patch from ddtrace.internal.compat import PY2 @@ -14,6 +15,7 @@ class TestHttplibPatch(PatchTestCase.Base): __module_name__ = "httplib" if PY2 else "http.client" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, http_client): pass @@ -24,5 +26,7 @@ def assert_not_module_patched(self, http_client): def assert_not_module_double_patched(self, http_client): pass - def assert_module_implements_get_version(self): - pass + def test_and_emit_get_version(self): + version = get_version() + assert type(version) == str + assert version == "" diff --git a/tests/contrib/httpx/test_httpx_patch_generated.py b/tests/contrib/httpx/test_httpx_patch.py similarity index 85% rename from tests/contrib/httpx/test_httpx_patch_generated.py rename to tests/contrib/httpx/test_httpx_patch.py index 5cb0db9c2d5..5062fb2c575 100644 --- a/tests/contrib/httpx/test_httpx_patch_generated.py +++ b/tests/contrib/httpx/test_httpx_patch.py @@ -19,6 +19,7 @@ class TestHttpxPatch(PatchTestCase.Base): __module_name__ = "httpx" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, httpx): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, httpx): def assert_not_module_double_patched(self, httpx): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/jinja2/test_jinja2_patch_generated.py b/tests/contrib/jinja2/test_jinja2_patch.py similarity index 85% rename from tests/contrib/jinja2/test_jinja2_patch_generated.py rename to tests/contrib/jinja2/test_jinja2_patch.py index 2b2306bc224..ec65e5276e3 100644 --- a/tests/contrib/jinja2/test_jinja2_patch_generated.py +++ b/tests/contrib/jinja2/test_jinja2_patch.py @@ -19,6 +19,7 @@ class TestJinja2Patch(PatchTestCase.Base): __module_name__ = "jinja2" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, jinja2): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, jinja2): def assert_not_module_double_patched(self, jinja2): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/kafka/test_kafka_patch.py b/tests/contrib/kafka/test_kafka_patch.py index d77e7f2915c..23adc8503af 100644 --- a/tests/contrib/kafka/test_kafka_patch.py +++ b/tests/contrib/kafka/test_kafka_patch.py @@ -9,6 +9,7 @@ class TestKafkaPatch(PatchTestCase.Base): __module_name__ = "confluent_kafka" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, confluent_kafka): self.assert_wrapped(confluent_kafka.Producer({}).produce) @@ -27,8 +28,3 @@ def assert_not_module_double_patched(self, confluent_kafka): self.assert_not_double_wrapped(confluent_kafka.Consumer({"group.id": "group_id"}).poll) self.assert_not_double_wrapped(confluent_kafka.SerializingProducer({}).produce) self.assert_not_double_wrapped(confluent_kafka.DeserializingConsumer({"group.id": "group_id"}).poll) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/kombu/test_kombu_patch_generated.py b/tests/contrib/kombu/test_kombu_patch.py similarity index 85% rename from tests/contrib/kombu/test_kombu_patch_generated.py rename to tests/contrib/kombu/test_kombu_patch.py index fe8dc1ef9c1..908cd920489 100644 --- a/tests/contrib/kombu/test_kombu_patch_generated.py +++ b/tests/contrib/kombu/test_kombu_patch.py @@ -19,6 +19,7 @@ class TestKombuPatch(PatchTestCase.Base): __module_name__ = "kombu" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, kombu): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, kombu): def assert_not_module_double_patched(self, kombu): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/langchain/test_langchain_patch.py b/tests/contrib/langchain/test_langchain_patch.py index b756634805c..132f38fa40a 100644 --- a/tests/contrib/langchain/test_langchain_patch.py +++ b/tests/contrib/langchain/test_langchain_patch.py @@ -11,6 +11,7 @@ class TestLangchainPatch(PatchTestCase.Base): __module_name__ = "langchain" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, langchain): self.assert_wrapped(langchain.llms.base.BaseLLM.generate) @@ -62,8 +63,3 @@ def assert_not_module_double_patched(self, langchain): vectorstore_interface = getattr(langchain.vectorstores, vectorstore, None) if vectorstore_interface: self.assert_not_double_wrapped(vectorstore_interface.similarity_search) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/logging/test_logging_patch_generated.py b/tests/contrib/logging/test_logging_patch.py similarity index 85% rename from tests/contrib/logging/test_logging_patch_generated.py rename to tests/contrib/logging/test_logging_patch.py index 939d00a69c1..94e4c975a81 100644 --- a/tests/contrib/logging/test_logging_patch_generated.py +++ b/tests/contrib/logging/test_logging_patch.py @@ -19,6 +19,7 @@ class TestLoggingPatch(PatchTestCase.Base): __module_name__ = "logging" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, logging): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, logging): def assert_not_module_double_patched(self, logging): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/mako/test_mako_patch_generated.py b/tests/contrib/mako/test_mako_patch.py similarity index 85% rename from tests/contrib/mako/test_mako_patch_generated.py rename to tests/contrib/mako/test_mako_patch.py index 8d7be5f588a..17e23677b0d 100644 --- a/tests/contrib/mako/test_mako_patch_generated.py +++ b/tests/contrib/mako/test_mako_patch.py @@ -19,6 +19,7 @@ class TestMakoPatch(PatchTestCase.Base): __module_name__ = "mako" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, mako): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, mako): def assert_not_module_double_patched(self, mako): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/mariadb/test_mariadb_patch_generated.py b/tests/contrib/mariadb/test_mariadb_patch.py similarity index 85% rename from tests/contrib/mariadb/test_mariadb_patch_generated.py rename to tests/contrib/mariadb/test_mariadb_patch.py index b232bca48b4..8dd47b216b3 100644 --- a/tests/contrib/mariadb/test_mariadb_patch_generated.py +++ b/tests/contrib/mariadb/test_mariadb_patch.py @@ -19,6 +19,7 @@ class TestMariadbPatch(PatchTestCase.Base): __module_name__ = "mariadb" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, mariadb): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, mariadb): def assert_not_module_double_patched(self, mariadb): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/molten/test_molten_patch_generated.py b/tests/contrib/molten/test_molten_patch.py similarity index 85% rename from tests/contrib/molten/test_molten_patch_generated.py rename to tests/contrib/molten/test_molten_patch.py index cf043b8948e..73a13a3e463 100644 --- a/tests/contrib/molten/test_molten_patch_generated.py +++ b/tests/contrib/molten/test_molten_patch.py @@ -19,6 +19,7 @@ class TestMoltenPatch(PatchTestCase.Base): __module_name__ = "molten" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, molten): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, molten): def assert_not_module_double_patched(self, molten): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/mongoengine/test_mongoengine_patch_generated.py b/tests/contrib/mongoengine/test_mongoengine_patch.py similarity index 86% rename from tests/contrib/mongoengine/test_mongoengine_patch_generated.py rename to tests/contrib/mongoengine/test_mongoengine_patch.py index a480f4a9488..f6d994cec0f 100644 --- a/tests/contrib/mongoengine/test_mongoengine_patch_generated.py +++ b/tests/contrib/mongoengine/test_mongoengine_patch.py @@ -19,6 +19,7 @@ class TestMongoenginePatch(PatchTestCase.Base): __module_name__ = "mongoengine" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, mongoengine): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, mongoengine): def assert_not_module_double_patched(self, mongoengine): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/mysql/test_mysql_patch_generated.py b/tests/contrib/mysql/test_mysql_patch.py similarity index 85% rename from tests/contrib/mysql/test_mysql_patch_generated.py rename to tests/contrib/mysql/test_mysql_patch.py index 34f3b4197ee..e69f9781cc4 100644 --- a/tests/contrib/mysql/test_mysql_patch_generated.py +++ b/tests/contrib/mysql/test_mysql_patch.py @@ -19,6 +19,7 @@ class TestMysqlPatch(PatchTestCase.Base): __module_name__ = "mysql.connector" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, mysql_connector): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, mysql_connector): def assert_not_module_double_patched(self, mysql_connector): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/mysqldb/test_mysqldb_patch_generated.py b/tests/contrib/mysqldb/test_mysqldb_patch.py similarity index 85% rename from tests/contrib/mysqldb/test_mysqldb_patch_generated.py rename to tests/contrib/mysqldb/test_mysqldb_patch.py index 9c14abadfd0..e17ce852f56 100644 --- a/tests/contrib/mysqldb/test_mysqldb_patch_generated.py +++ b/tests/contrib/mysqldb/test_mysqldb_patch.py @@ -19,6 +19,7 @@ class TestMysqldbPatch(PatchTestCase.Base): __module_name__ = "MySQLdb" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, MySQLdb): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, MySQLdb): def assert_not_module_double_patched(self, MySQLdb): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/openai/test_openai.py b/tests/contrib/openai/test_openai.py index a4ae7de633e..ac77158d980 100644 --- a/tests/contrib/openai/test_openai.py +++ b/tests/contrib/openai/test_openai.py @@ -15,7 +15,6 @@ from ddtrace import Pin from ddtrace import Span from ddtrace import patch -from ddtrace.contrib.openai.patch import get_version from ddtrace.contrib.openai.patch import unpatch from ddtrace.contrib.openai.utils import _est_tokens from ddtrace.filters import TraceFilter @@ -197,12 +196,6 @@ def iswrapped(obj): return hasattr(obj, "__dd_wrapped__") -def test_module_implements_get_version(): - version = get_version() - assert type(version) == str - assert version != "" - - def test_patching(openai): """Ensure that the correct objects are patched and not double patched.""" diff --git a/tests/contrib/openai/test_openai_patch.py b/tests/contrib/openai/test_openai_patch.py index c2976330684..e2fa8cb88c3 100644 --- a/tests/contrib/openai/test_openai_patch.py +++ b/tests/contrib/openai/test_openai_patch.py @@ -1 +1,31 @@ -# Refer to test_openai::test_patching +# 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.openai import get_version +from ddtrace.contrib.openai.patch import patch + + +try: + from ddtrace.contrib.openai.patch import unpatch +except ImportError: + unpatch = None +from tests.contrib.patch import PatchTestCase + + +class TestOpenaiPatch(PatchTestCase.Base): + __integration_name__ = "openai" + __module_name__ = "openai" + __patch_func__ = patch + __unpatch_func__ = unpatch + __get_version__ = get_version + + def assert_module_patched(self, openai): + pass + + def assert_not_module_patched(self, openai): + pass + + def assert_not_module_double_patched(self, openai): + pass diff --git a/tests/contrib/patch.py b/tests/contrib/patch.py index 23a6bf0c3e7..5ef41339fdc 100644 --- a/tests/contrib/patch.py +++ b/tests/contrib/patch.py @@ -1,5 +1,6 @@ import functools import importlib +import json import os import sys from tempfile import NamedTemporaryFile @@ -8,11 +9,16 @@ import wrapt +from ddtrace.internal.compat import httplib +from ddtrace.version import get_version from tests.subprocesstest import SubprocessTestCase from tests.subprocesstest import run_in_subprocess from tests.utils import call_program +TRACER_VERSION = get_version() + + class PatchMixin(unittest.TestCase): """ TestCase for testing the patch logic of an integration. @@ -99,6 +105,24 @@ def wrapper(self, *args, **kwargs): return wrapper +def emit_integration_and_version_to_test_agent(integration_name, version, module_name=None): + # Define the data payload + data = { + "integration_name": integration_name, + "integration_version": version, + "tracer_version": TRACER_VERSION, + "tracer_language": "python", + # we want the toplevel module name: ie for snowflake.connector, we want snowflake + "dependency_name": module_name.split(".")[0] if module_name else integration_name, + } + payload = json.dumps(data) + conn = httplib.HTTPConnection(host="localhost", port=9126, timeout=10) + headers = {"Content-type": "application/json"} + conn.request("PUT", "/test/session/integrations", body=payload, headers=headers) + response = conn.getresponse() + assert response.status == 200 + + class PatchTestCase(object): """ unittest or other test runners will pick up the base test case as a testcase @@ -154,6 +178,8 @@ def test_patch_import(self): __module_name__ = None __patch_func__ = None __unpatch_func__ = None + __get_version__ = None + __get_versions__ = None def __init__(self, *args, **kwargs): # DEV: Python will wrap a function when assigning it to a class as an @@ -177,6 +203,24 @@ def patch(): patch_func() self.__patch_func__ = patch + + # Same for __get_version__() + if self.__get_version__: + get_version_func = self.__get_version__.__func__ + + def get_version(): + return get_version_func() + + self.__get_version__ = get_version + + # Same for __get_version__() + if self.__get_versions__: + get_versions_func = self.__get_versions__.__func__ + + def get_versions(): + get_versions_func() + + self.__get_versions__ = get_versions super(PatchTestCase.Base, self).__init__(*args, **kwargs) def _gen_test_attrs(self, ops): @@ -297,12 +341,6 @@ def assert_not_module_double_patched(self, redis): """ raise NotImplementedError(self.assert_not_module_double_patched.__doc__) - def assert_module_implements_get_version(self): - """ - Module patch should implement get_version returning the str version - """ - raise NotImplementedError(self.assert_module_implements_get_version.__doc__) - @raise_if_no_attrs def test_import_patch(self): """ @@ -323,12 +361,6 @@ def test_import_patch(self): self.__patch_func__() self.assert_module_patched(module) - def test_get_version(self): - """ - Module patch should implement get_version returning the str version - """ - self.assert_module_implements_get_version() - @raise_if_no_attrs def test_patch_import(self): """ @@ -737,3 +769,23 @@ def patch_wrapper(wrapped, _, args, kwrags): out, err, _, _ = call_program("ddtrace-run", sys.executable, f.name, env=env) self.assertEqual(out, b"OK", "stderr:\n%s" % err.decode()) + + def test_and_emit_get_version(self): + """Each contrib module should implement a get_version() function. This function is used for + the APM Telemetry integrations payload event, and by APM analytics to inform of dd-trace-py + current supported integration versions. + """ + if hasattr(self, "__get_versions__") and self.__get_versions__ is not None: + assert self.__get_version__() == "" + versions = self.__get_versions__() + assert self.__module_name__ in versions + assert versions[self.__module_name__] != "" + for name, v in versions.items(): + emit_integration_and_version_to_test_agent(self.__integration_name__, v, module_name=name) + else: + version = self.__get_version__() + assert type(version) == str + assert version != "" + emit_integration_and_version_to_test_agent( + self.__integration_name__, version, module_name=self.__module_name__ + ) diff --git a/tests/contrib/psycopg/test_psycopg_patch_generated.py b/tests/contrib/psycopg/test_psycopg_patch.py similarity index 77% rename from tests/contrib/psycopg/test_psycopg_patch_generated.py rename to tests/contrib/psycopg/test_psycopg_patch.py index a8b0a9148a0..8d91b2b07d7 100644 --- a/tests/contrib/psycopg/test_psycopg_patch_generated.py +++ b/tests/contrib/psycopg/test_psycopg_patch.py @@ -13,6 +13,7 @@ except ImportError: unpatch = None from tests.contrib.patch import PatchTestCase +from tests.contrib.patch import emit_integration_and_version_to_test_agent class TestPsycopgPatch(PatchTestCase.Base): @@ -20,6 +21,8 @@ class TestPsycopgPatch(PatchTestCase.Base): __module_name__ = "psycopg" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version + __get_versions__ = get_versions def assert_module_patched(self, psycopg): pass @@ -30,10 +33,10 @@ def assert_not_module_patched(self, psycopg): def assert_not_module_double_patched(self, psycopg): pass - def assert_module_implements_get_version(self): + def test_and_emit_get_version(self): patch() assert get_version() == "" versions = get_versions() - assert "psycopg" in versions - assert versions["psycopg"] != "" + assert versions.get("psycopg") + emit_integration_and_version_to_test_agent("psycopg", versions["psycopg"]) unpatch() diff --git a/tests/contrib/psycopg2/test_psycopg_patch_generated.py b/tests/contrib/psycopg2/test_psycopg_patch.py similarity index 76% rename from tests/contrib/psycopg2/test_psycopg_patch_generated.py rename to tests/contrib/psycopg2/test_psycopg_patch.py index 0598d7a301f..21172763b77 100644 --- a/tests/contrib/psycopg2/test_psycopg_patch_generated.py +++ b/tests/contrib/psycopg2/test_psycopg_patch.py @@ -13,6 +13,7 @@ except ImportError: unpatch = None from tests.contrib.patch import PatchTestCase +from tests.contrib.patch import emit_integration_and_version_to_test_agent class TestPsycopgPatch(PatchTestCase.Base): @@ -20,6 +21,8 @@ class TestPsycopgPatch(PatchTestCase.Base): __module_name__ = "psycopg2" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version + __get_versions__ = get_versions def assert_module_patched(self, psycopg): pass @@ -30,10 +33,10 @@ def assert_not_module_patched(self, psycopg): def assert_not_module_double_patched(self, psycopg): pass - def assert_module_implements_get_version(self): + def test_and_emit_get_version(self): patch() assert get_version() == "" versions = get_versions() - assert "psycopg2" in versions - assert versions["psycopg2"] != "" + assert versions.get("psycopg2") + emit_integration_and_version_to_test_agent("psycopg", versions["psycopg2"], "psycopg2") unpatch() diff --git a/tests/contrib/pylibmc/test_pylibmc_patch_generated.py b/tests/contrib/pylibmc/test_pylibmc_patch.py similarity index 85% rename from tests/contrib/pylibmc/test_pylibmc_patch_generated.py rename to tests/contrib/pylibmc/test_pylibmc_patch.py index 37b9b44c6c0..1ca3c413827 100644 --- a/tests/contrib/pylibmc/test_pylibmc_patch_generated.py +++ b/tests/contrib/pylibmc/test_pylibmc_patch.py @@ -19,6 +19,7 @@ class TestPylibmcPatch(PatchTestCase.Base): __module_name__ = "pylibmc" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pylibmc): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pylibmc): def assert_not_module_double_patched(self, pylibmc): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pylons/test_pylons_patch_generated.py b/tests/contrib/pylons/test_pylons_patch.py similarity index 85% rename from tests/contrib/pylons/test_pylons_patch_generated.py rename to tests/contrib/pylons/test_pylons_patch.py index 0658a05c06f..8bb0cbefba9 100644 --- a/tests/contrib/pylons/test_pylons_patch_generated.py +++ b/tests/contrib/pylons/test_pylons_patch.py @@ -19,6 +19,7 @@ class TestPylonsPatch(PatchTestCase.Base): __module_name__ = "pylons.wsgiapp" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pylons_wsgiapp): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pylons_wsgiapp): def assert_not_module_double_patched(self, pylons_wsgiapp): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pymemcache/test_pymemcache_patch_generated.py b/tests/contrib/pymemcache/test_pymemcache_patch.py similarity index 86% rename from tests/contrib/pymemcache/test_pymemcache_patch_generated.py rename to tests/contrib/pymemcache/test_pymemcache_patch.py index 2b383eb831e..fcedad008c1 100644 --- a/tests/contrib/pymemcache/test_pymemcache_patch_generated.py +++ b/tests/contrib/pymemcache/test_pymemcache_patch.py @@ -19,6 +19,7 @@ class TestPymemcachePatch(PatchTestCase.Base): __module_name__ = "pymemcache" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pymemcache): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pymemcache): def assert_not_module_double_patched(self, pymemcache): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pymongo/test_pymongo_patch_generated.py b/tests/contrib/pymongo/test_pymongo_patch.py similarity index 85% rename from tests/contrib/pymongo/test_pymongo_patch_generated.py rename to tests/contrib/pymongo/test_pymongo_patch.py index 32a1e27b5a5..3596beca648 100644 --- a/tests/contrib/pymongo/test_pymongo_patch_generated.py +++ b/tests/contrib/pymongo/test_pymongo_patch.py @@ -19,6 +19,7 @@ class TestPymongoPatch(PatchTestCase.Base): __module_name__ = "pymongo" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pymongo): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pymongo): def assert_not_module_double_patched(self, pymongo): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pymysql/test_pymysql_patch_generated.py b/tests/contrib/pymysql/test_pymysql_patch.py similarity index 85% rename from tests/contrib/pymysql/test_pymysql_patch_generated.py rename to tests/contrib/pymysql/test_pymysql_patch.py index 790b95ed9e2..cb48bcda3dd 100644 --- a/tests/contrib/pymysql/test_pymysql_patch_generated.py +++ b/tests/contrib/pymysql/test_pymysql_patch.py @@ -19,6 +19,7 @@ class TestPymysqlPatch(PatchTestCase.Base): __module_name__ = "pymysql" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pymysql): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pymysql): def assert_not_module_double_patched(self, pymysql): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pynamodb/test_pynamodb_patch_generated.py b/tests/contrib/pynamodb/test_pynamodb_patch.py similarity index 86% rename from tests/contrib/pynamodb/test_pynamodb_patch_generated.py rename to tests/contrib/pynamodb/test_pynamodb_patch.py index 607c8532463..36034c9dabc 100644 --- a/tests/contrib/pynamodb/test_pynamodb_patch_generated.py +++ b/tests/contrib/pynamodb/test_pynamodb_patch.py @@ -19,6 +19,7 @@ class TestPynamodbPatch(PatchTestCase.Base): __module_name__ = "pynamodb.connection.base" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pynamodb_connection_base): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pynamodb_connection_base): def assert_not_module_double_patched(self, pynamodb_connection_base): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pyodbc/test_pyodbc_patch_generated.py b/tests/contrib/pyodbc/test_pyodbc_patch.py similarity index 85% rename from tests/contrib/pyodbc/test_pyodbc_patch_generated.py rename to tests/contrib/pyodbc/test_pyodbc_patch.py index d08806661c6..29ad4204d6a 100644 --- a/tests/contrib/pyodbc/test_pyodbc_patch_generated.py +++ b/tests/contrib/pyodbc/test_pyodbc_patch.py @@ -19,6 +19,7 @@ class TestPyodbcPatch(PatchTestCase.Base): __module_name__ = "pyodbc" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pyodbc): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pyodbc): def assert_not_module_double_patched(self, pyodbc): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pyramid/test_pyramid_patch_generated.py b/tests/contrib/pyramid/test_pyramid_patch.py similarity index 85% rename from tests/contrib/pyramid/test_pyramid_patch_generated.py rename to tests/contrib/pyramid/test_pyramid_patch.py index 8fd0229ee67..7aec4658e25 100644 --- a/tests/contrib/pyramid/test_pyramid_patch_generated.py +++ b/tests/contrib/pyramid/test_pyramid_patch.py @@ -19,6 +19,7 @@ class TestPyramidPatch(PatchTestCase.Base): __module_name__ = "pyramid" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, pyramid): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, pyramid): def assert_not_module_double_patched(self, pyramid): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/pytest/test_pytest.py b/tests/contrib/pytest/test_pytest.py index 2571d0f9886..59ab41e73c9 100644 --- a/tests/contrib/pytest/test_pytest.py +++ b/tests/contrib/pytest/test_pytest.py @@ -21,6 +21,7 @@ from ddtrace.internal.ci_visibility.encoder import CIVisibilityEncoderV01 from ddtrace.internal.compat import PY2 from tests.ci_visibility.util import _patch_dummy_writer +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import TracerTestCase from tests.utils import override_env @@ -52,11 +53,13 @@ def subprocess_run(self, *args): with override_env(dict(DD_API_KEY="foobar.baz")): return self.testdir.runpytest_subprocess(*args) - def test_module_implements_get_version(self): + def test_and_emit_get_version(self): version = get_version() assert type(version) == str assert version != "" + emit_integration_and_version_to_test_agent("pytest", version) + @pytest.mark.skipif(sys.version_info[0] == 2, reason="Triggers a bug with coverage, sqlite and Python 2") def test_patch_all(self): """Test with --ddtrace-patch-all.""" diff --git a/tests/contrib/pytest_bdd/test_pytest_bdd.py b/tests/contrib/pytest_bdd/test_pytest_bdd.py index c91c9973888..3b58da9c579 100644 --- a/tests/contrib/pytest_bdd/test_pytest_bdd.py +++ b/tests/contrib/pytest_bdd/test_pytest_bdd.py @@ -12,6 +12,7 @@ from ddtrace.ext import test from ddtrace.internal.ci_visibility import CIVisibility from tests.ci_visibility.util import _patch_dummy_writer +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import DummyCIVisibilityWriter from tests.utils import TracerTestCase from tests.utils import override_env @@ -52,11 +53,13 @@ def subprocess_run(self, *args): """Execute test script with test tracer.""" return self.testdir.runpytest_subprocess(*args) - def test_module_implements_get_version(self): + def test_and_emit_get_version(self): version = get_version() assert type(version) == str assert version != "" + emit_integration_and_version_to_test_agent("pytest-bdd", version) + def test_pytest_bdd_scenario_with_parameters(self): """Test that pytest-bdd traces scenario with all steps.""" self.testdir.makefile( diff --git a/tests/contrib/redis/test_redis_patch_generated.py b/tests/contrib/redis/test_redis_patch.py similarity index 85% rename from tests/contrib/redis/test_redis_patch_generated.py rename to tests/contrib/redis/test_redis_patch.py index 273f2ee1863..e1768baf76b 100644 --- a/tests/contrib/redis/test_redis_patch_generated.py +++ b/tests/contrib/redis/test_redis_patch.py @@ -19,6 +19,7 @@ class TestRedisPatch(PatchTestCase.Base): __module_name__ = "redis" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, redis): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, redis): def assert_not_module_double_patched(self, redis): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/rediscluster/test_rediscluster_patch_generated.py b/tests/contrib/rediscluster/test_rediscluster_patch.py similarity index 86% rename from tests/contrib/rediscluster/test_rediscluster_patch_generated.py rename to tests/contrib/rediscluster/test_rediscluster_patch.py index 26587abb85b..c95dbf73e7c 100644 --- a/tests/contrib/rediscluster/test_rediscluster_patch_generated.py +++ b/tests/contrib/rediscluster/test_rediscluster_patch.py @@ -19,6 +19,7 @@ class TestRedisclusterPatch(PatchTestCase.Base): __module_name__ = "rediscluster" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, rediscluster): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, rediscluster): def assert_not_module_double_patched(self, rediscluster): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/requests/test_requests_patch_generated.py b/tests/contrib/requests/test_requests_patch.py similarity index 85% rename from tests/contrib/requests/test_requests_patch_generated.py rename to tests/contrib/requests/test_requests_patch.py index b7e94b3343d..d6824627405 100644 --- a/tests/contrib/requests/test_requests_patch_generated.py +++ b/tests/contrib/requests/test_requests_patch.py @@ -19,6 +19,7 @@ class TestRequestsPatch(PatchTestCase.Base): __module_name__ = "requests" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, requests): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, requests): def assert_not_module_double_patched(self, requests): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/rq/test_rq.py b/tests/contrib/rq/test_rq.py index b4c20747d72..0d5197f05ac 100644 --- a/tests/contrib/rq/test_rq.py +++ b/tests/contrib/rq/test_rq.py @@ -11,6 +11,7 @@ from ddtrace.contrib.rq import get_version from ddtrace.contrib.rq import patch from ddtrace.contrib.rq import unpatch +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import override_config from tests.utils import snapshot from tests.utils import snapshot_context @@ -58,11 +59,13 @@ def test_sync_queue_enqueue(sync_queue): sync_queue.enqueue(job_add1, 1) -def test_module_implements_get_version(): +def test_and_implement_get_version(): version = get_version() assert type(version) == str assert version != "" + emit_integration_and_version_to_test_agent("rq", version) + @snapshot(ignores=snapshot_ignores, variants={"": rq_version >= (1, 10, 1), "pre_1_10_1": rq_version < (1, 10, 1)}) def test_queue_failing_job(sync_queue): diff --git a/tests/contrib/sanic/test_sanic_patch_generated.py b/tests/contrib/sanic/test_sanic_patch.py similarity index 85% rename from tests/contrib/sanic/test_sanic_patch_generated.py rename to tests/contrib/sanic/test_sanic_patch.py index ea17c127028..2ef66abf386 100644 --- a/tests/contrib/sanic/test_sanic_patch_generated.py +++ b/tests/contrib/sanic/test_sanic_patch.py @@ -19,6 +19,7 @@ class TestSanicPatch(PatchTestCase.Base): __module_name__ = "sanic" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, sanic): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, sanic): def assert_not_module_double_patched(self, sanic): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/snowflake/test_snowflake_patch.py b/tests/contrib/snowflake/test_snowflake_patch.py index 55c31765e84..682e55e95d7 100644 --- a/tests/contrib/snowflake/test_snowflake_patch.py +++ b/tests/contrib/snowflake/test_snowflake_patch.py @@ -8,6 +8,7 @@ class TestSnowflakePatch(PatchTestCase.Base): __module_name__ = "snowflake.connector" __patch_func__ = patch __unpatch_func__ = None + __get_version__ = get_version def assert_module_patched(self, snowflake): self.assert_wrapped(snowflake.connect) @@ -17,8 +18,3 @@ def assert_not_module_patched(self, snowflake): def assert_not_module_double_patched(self, snowflake): self.assert_not_double_wrapped(snowflake.connect) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/sqlalchemy/test_patch.py b/tests/contrib/sqlalchemy/test_patch.py index 2105235924c..43b1c834d49 100644 --- a/tests/contrib/sqlalchemy/test_patch.py +++ b/tests/contrib/sqlalchemy/test_patch.py @@ -5,6 +5,7 @@ from ddtrace.contrib.sqlalchemy import get_version from ddtrace.contrib.sqlalchemy import patch from ddtrace.contrib.sqlalchemy import unpatch +from tests.contrib.patch import emit_integration_and_version_to_test_agent from tests.utils import TracerTestCase from tests.utils import assert_is_measured @@ -107,7 +108,9 @@ def test_analytics_sample_rate(self): assert root.get_metric(ANALYTICS_SAMPLE_RATE_KEY) == metric_value self.reset() - def test_module_implements_get_version(self): + def test_and_emit_get_version(self): version = get_version() assert type(version) == str assert version != "" + + emit_integration_and_version_to_test_agent("sqlalchemy", version) diff --git a/tests/contrib/sqlite3/test_sqlite3.py b/tests/contrib/sqlite3/test_sqlite3.py index 28cc9517307..489e7047dba 100644 --- a/tests/contrib/sqlite3/test_sqlite3.py +++ b/tests/contrib/sqlite3/test_sqlite3.py @@ -12,7 +12,6 @@ from ddtrace.constants import ERROR_STACK from ddtrace.constants import ERROR_TYPE from ddtrace.contrib.sqlite3.patch import TracedSQLiteCursor -from ddtrace.contrib.sqlite3.patch import get_version from ddtrace.contrib.sqlite3.patch import patch from ddtrace.contrib.sqlite3.patch import unpatch from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME @@ -471,9 +470,3 @@ def test_backup(patched_conn): with destination: patched_conn.backup(destination, pages=1) - - -def test_module_implements_get_version(): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/sqlite3/test_sqlite3_patch.py b/tests/contrib/sqlite3/test_sqlite3_patch.py new file mode 100644 index 00000000000..ab19d63c141 --- /dev/null +++ b/tests/contrib/sqlite3/test_sqlite3_patch.py @@ -0,0 +1,31 @@ +# 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.sqlite3 import get_version +from ddtrace.contrib.sqlite3.patch import patch + + +try: + from ddtrace.contrib.sqlite3.patch import unpatch +except ImportError: + unpatch = None +from tests.contrib.patch import PatchTestCase + + +class TestSqlite3Patch(PatchTestCase.Base): + __integration_name__ = "sqlite3" + __module_name__ = "sqlite3" + __patch_func__ = patch + __unpatch_func__ = unpatch + __get_version__ = get_version + + def assert_module_patched(self, sqlite3): + pass + + def assert_not_module_patched(self, sqlite3): + pass + + def assert_not_module_double_patched(self, sqlite3): + pass diff --git a/tests/contrib/starlette/test_starlette_patch.py b/tests/contrib/starlette/test_starlette_patch.py index ffed93aa2dd..6666ad764a9 100644 --- a/tests/contrib/starlette/test_starlette_patch.py +++ b/tests/contrib/starlette/test_starlette_patch.py @@ -9,6 +9,7 @@ class TestStarlettePatch(PatchTestCase.Base): __module_name__ = "starlette" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, starlette): self.assert_wrapped(starlette.applications.Starlette.__init__) @@ -26,8 +27,3 @@ def assert_not_module_double_patched(self, starlette): self.assert_not_double_wrapped(starlette.applications.Starlette.__init__) self.assert_not_double_wrapped(starlette.routing.Mount.handle) self.assert_not_double_wrapped(starlette.routing.Route.handle) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/subprocess/test_subprocess_patch.py b/tests/contrib/subprocess/test_subprocess_patch.py index f9dab759eb1..cb0c785991e 100644 --- a/tests/contrib/subprocess/test_subprocess_patch.py +++ b/tests/contrib/subprocess/test_subprocess_patch.py @@ -1,4 +1,5 @@ from ddtrace import config +from ddtrace.contrib.subprocess.patch import get_version from ddtrace.contrib.subprocess.patch import patch @@ -14,6 +15,7 @@ class TestSubprocessPatch(PatchTestCase.Base): __module_name__ = "subprocess" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def __init__(self, *args, **kwargs): config._appsec_enabled = True @@ -31,9 +33,6 @@ def assert_not_module_double_patched(self, subprocess): self.assert_not_double_wrapped(subprocess.Popen.__init__) self.assert_not_double_wrapped(subprocess.Popen.wait) - def assert_module_implements_get_version(self): - pass - # These are disabled because the base class uses @run_in_subprocess which # import subprocess before we have a chance to patch. However, the contrib # unittests already test patch and unpatch @@ -54,3 +53,8 @@ def test_patch_unpatch_unpatch_import(self): def test_unpatch_patch_import(self): pass + + def test_and_emit_get_version(self): + version = get_version() + assert type(version) == str + assert version == "" diff --git a/tests/contrib/tornado/test_tornado_patch_generated.py b/tests/contrib/tornado/test_tornado_patch.py similarity index 85% rename from tests/contrib/tornado/test_tornado_patch_generated.py rename to tests/contrib/tornado/test_tornado_patch.py index bcba5a4f89b..0f9963ab532 100644 --- a/tests/contrib/tornado/test_tornado_patch_generated.py +++ b/tests/contrib/tornado/test_tornado_patch.py @@ -19,6 +19,7 @@ class TestTornadoPatch(PatchTestCase.Base): __module_name__ = "tornado" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, tornado): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, tornado): def assert_not_module_double_patched(self, tornado): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/unittest_plugin/test_unittest_patch.py b/tests/contrib/unittest_plugin/test_unittest_patch.py new file mode 100644 index 00000000000..ff7e10d2064 --- /dev/null +++ b/tests/contrib/unittest_plugin/test_unittest_patch.py @@ -0,0 +1,36 @@ +# 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.unittest import get_version +from ddtrace.contrib.unittest.patch import patch + + +try: + from ddtrace.contrib.unittest.patch import unpatch +except ImportError: + unpatch = None +from tests.contrib.patch import PatchTestCase + + +class TestUnittestPatch(PatchTestCase.Base): + __integration_name__ = "unittest" + __module_name__ = "unittest" + __patch_func__ = patch + __unpatch_func__ = unpatch + __get_version__ = get_version + + def assert_module_patched(self, unittest): + pass + + def assert_not_module_patched(self, unittest): + pass + + def assert_not_module_double_patched(self, unittest): + pass + + def test_and_emit_get_version(self): + version = get_version() + assert type(version) == str + assert version == "" diff --git a/tests/contrib/urllib3/test_urllib3_patch.py b/tests/contrib/urllib3/test_urllib3_patch.py index 51b98c7a348..ace147d715c 100644 --- a/tests/contrib/urllib3/test_urllib3_patch.py +++ b/tests/contrib/urllib3/test_urllib3_patch.py @@ -9,6 +9,7 @@ class TestUrllib3Patch(PatchTestCase.Base): __module_name__ = "urllib3" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, urllib3): self.assert_wrapped(urllib3.connectionpool.HTTPConnectionPool.urlopen) @@ -18,8 +19,3 @@ def assert_not_module_patched(self, urllib3): def assert_not_module_double_patched(self, urllib3): self.assert_not_double_wrapped(urllib3.connectionpool.HTTPConnectionPool.urlopen) - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/vertica/test_vertica_patch_generated.py b/tests/contrib/vertica/test_vertica_patch.py similarity index 86% rename from tests/contrib/vertica/test_vertica_patch_generated.py rename to tests/contrib/vertica/test_vertica_patch.py index b4fb1e26232..bdaccf5d7e2 100644 --- a/tests/contrib/vertica/test_vertica_patch_generated.py +++ b/tests/contrib/vertica/test_vertica_patch.py @@ -19,6 +19,7 @@ class TestVerticaPatch(PatchTestCase.Base): __module_name__ = "vertica_python" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, vertica_python): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, vertica_python): def assert_not_module_double_patched(self, vertica_python): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != "" diff --git a/tests/contrib/yaaredis/test_yaaredis_patch_generated.py b/tests/contrib/yaaredis/test_yaaredis_patch.py similarity index 85% rename from tests/contrib/yaaredis/test_yaaredis_patch_generated.py rename to tests/contrib/yaaredis/test_yaaredis_patch.py index c2526fbf18d..1d78fe9458c 100644 --- a/tests/contrib/yaaredis/test_yaaredis_patch_generated.py +++ b/tests/contrib/yaaredis/test_yaaredis_patch.py @@ -19,6 +19,7 @@ class TestYaaredisPatch(PatchTestCase.Base): __module_name__ = "yaaredis" __patch_func__ = patch __unpatch_func__ = unpatch + __get_version__ = get_version def assert_module_patched(self, yaaredis): pass @@ -28,8 +29,3 @@ def assert_not_module_patched(self, yaaredis): def assert_not_module_double_patched(self, yaaredis): pass - - def assert_module_implements_get_version(self): - version = get_version() - assert type(version) == str - assert version != ""