From ee2d708f6a3192961f6cb29bed2d97f5d3af830f Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Wed, 2 Aug 2023 15:43:57 -0700 Subject: [PATCH 1/6] Replaced pkg_resources with importlib.metadata --- newrelic/admin/__init__.py | 69 +++++++++--------- newrelic/common/package_version_utils.py | 1 + newrelic/config.py | 22 ++++-- newrelic/hooks/framework_pyramid.py | 54 +++++++------- tests/adapter_hypercorn/test_hypercorn.py | 9 ++- .../test_append_slash_app.py | 71 ++++++++++--------- 6 files changed, 122 insertions(+), 104 deletions(-) diff --git a/newrelic/admin/__init__.py b/newrelic/admin/__init__.py index e41599a318..888fd9ab63 100644 --- a/newrelic/admin/__init__.py +++ b/newrelic/admin/__init__.py @@ -14,27 +14,26 @@ from __future__ import print_function -import sys import logging +import sys _builtin_plugins = [ - 'debug_console', - 'generate_config', - 'license_key', - 'local_config', - 'network_config', - 'record_deploy', - 'run_program', - 'run_python', - 'server_config', - 'validate_config' + "debug_console", + "generate_config", + "license_key", + "local_config", + "network_config", + "record_deploy", + "run_program", + "run_python", + "server_config", + "validate_config", ] _commands = {} -def command(name, options='', description='', hidden=False, - log_intercept=True, deprecated=False): +def command(name, options="", description="", hidden=False, log_intercept=True, deprecated=False): def wrapper(callback): callback.name = name callback.options = options @@ -44,6 +43,7 @@ def wrapper(callback): callback.deprecated = deprecated _commands[name] = callback return callback + return wrapper @@ -51,15 +51,15 @@ def usage(name): details = _commands[name] if details.deprecated: print("[WARNING] This command is deprecated and will be removed") - print('Usage: newrelic-admin %s %s' % (name, details.options)) + print("Usage: newrelic-admin %s %s" % (name, details.options)) -@command('help', '[command]', hidden=True) +@command("help", "[command]", hidden=True) def help(args): if not args: - print('Usage: newrelic-admin command [options]') + print("Usage: newrelic-admin command [options]") print() - print("Type 'newrelic-admin help '", end='') + print("Type 'newrelic-admin help '", end="") print("for help on a specific command.") print() print("Available commands are:") @@ -68,24 +68,24 @@ def help(args): for name in commands: details = _commands[name] if not details.hidden: - print(' ', name) + print(" ", name) else: name = args[0] if name not in _commands: - print("Unknown command '%s'." % name, end=' ') + print("Unknown command '%s'." % name, end=" ") print("Type 'newrelic-admin help' for usage.") else: details = _commands[name] - print('Usage: newrelic-admin %s %s' % (name, details.options)) + print("Usage: newrelic-admin %s %s" % (name, details.options)) if details.description: print() description = details.description if details.deprecated: - description = '[DEPRECATED] ' + description + description = "[DEPRECATED] " + description print(description) @@ -99,7 +99,7 @@ def emit(self, record): if len(logging.root.handlers) != 0: return - if record.name.startswith('newrelic.packages'): + if record.name.startswith("newrelic.packages"): return if record.levelno < logging.WARNING: @@ -107,9 +107,9 @@ def emit(self, record): return logging.StreamHandler.emit(self, record) - _stdout_logger = logging.getLogger('newrelic') + _stdout_logger = logging.getLogger("newrelic") _stdout_handler = FilteredStreamHandler(sys.stdout) - _stdout_format = '%(levelname)s - %(message)s\n' + _stdout_format = "%(levelname)s - %(message)s\n" _stdout_formatter = logging.Formatter(_stdout_format) _stdout_handler.setFormatter(_stdout_formatter) _stdout_logger.addHandler(_stdout_handler) @@ -117,19 +117,24 @@ def emit(self, record): def load_internal_plugins(): for name in _builtin_plugins: - module_name = '%s.%s' % (__name__, name) + module_name = "%s.%s" % (__name__, name) __import__(module_name) def load_external_plugins(): try: - import pkg_resources + # since Python 3.8 + from importlib.metadata import entry_points except ImportError: - return + try: + # Deprecated in Python 3.12 + from pkg_resources import iter_entry_points as entry_points + except ImportError: + return - group = 'newrelic.admin' + group = "newrelic.admin" - for entrypoint in pkg_resources.iter_entry_points(group=group): + for entrypoint in entry_points(group=group): __import__(entrypoint.module_name) @@ -138,12 +143,12 @@ def main(): if len(sys.argv) > 1: command = sys.argv[1] else: - command = 'help' + command = "help" callback = _commands[command] except Exception: - print("Unknown command '%s'." % command, end='') + print("Unknown command '%s'." % command, end="") print("Type 'newrelic-admin help' for usage.") sys.exit(1) @@ -156,5 +161,5 @@ def main(): load_internal_plugins() load_external_plugins() -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/newrelic/common/package_version_utils.py b/newrelic/common/package_version_utils.py index f3d334e2a6..2ae3f98faf 100644 --- a/newrelic/common/package_version_utils.py +++ b/newrelic/common/package_version_utils.py @@ -93,6 +93,7 @@ def _get_package_version(name): except Exception: pass + # pkg_resources has been deprecated in Python 3.12 if "pkg_resources" in sys.modules: try: version = sys.modules["pkg_resources"].get_distribution(name).version diff --git a/newrelic/config.py b/newrelic/config.py index 797b223507..62e664e029 100644 --- a/newrelic/config.py +++ b/newrelic/config.py @@ -3097,13 +3097,18 @@ def _process_module_builtin_defaults(): def _process_module_entry_points(): try: - import pkg_resources + # since Python 3.8 + from importlib.metadata import entry_points except ImportError: - return + try: + # Deprecated in Python 3.12 + from pkg_resources import iter_entry_points as entry_points + except ImportError: + return group = "newrelic.hooks" - for entrypoint in pkg_resources.iter_entry_points(group=group): + for entrypoint in entry_points(group=group): target = entrypoint.name if target in _module_import_hook_registry: @@ -3161,13 +3166,18 @@ def _setup_instrumentation(): def _setup_extensions(): try: - import pkg_resources + # since Python 3.8 + from importlib.metadata import entry_points except ImportError: - return + try: + # Deprecated in Python 3.12 + from pkg_resources import iter_entry_points as entry_points + except ImportError: + return group = "newrelic.extension" - for entrypoint in pkg_resources.iter_entry_points(group=group): + for entrypoint in entry_points(group=group): __import__(entrypoint.module_name) module = sys.modules[entrypoint.module_name] module.initialize() diff --git a/newrelic/hooks/framework_pyramid.py b/newrelic/hooks/framework_pyramid.py index efe3c4468e..2393ad362f 100644 --- a/newrelic/hooks/framework_pyramid.py +++ b/newrelic/hooks/framework_pyramid.py @@ -48,25 +48,23 @@ from newrelic.api.transaction import current_transaction from newrelic.api.wsgi_application import wrap_wsgi_application from newrelic.common.object_names import callable_name -from newrelic.common.object_wrapper import (FunctionWrapper, wrap_out_function, - wrap_function_wrapper) +from newrelic.common.object_wrapper import ( + FunctionWrapper, + wrap_function_wrapper, + wrap_out_function, +) +from newrelic.common.package_version_utils import get_package_version def instrument_pyramid_router(module): - pyramid_version = None + pyramid_version = get_package_version("pyramid") - try: - import pkg_resources - pyramid_version = pkg_resources.get_distribution('pyramid').version - except Exception: - pass - - wrap_wsgi_application( - module, 'Router.__call__', framework=('Pyramid', pyramid_version)) + wrap_wsgi_application(module, "Router.__call__", framework=("Pyramid", pyramid_version)) def status_code(exc, value, tb): from pyramid.httpexceptions import HTTPException + # Ignore certain exceptions based on HTTP status codes. if isinstance(value, HTTPException): @@ -75,6 +73,7 @@ def status_code(exc, value, tb): def should_ignore(exc, value, tb): from pyramid.exceptions import PredicateMismatch + # Always ignore PredicateMismatch as it is raised by views to force # subsequent views to be consulted when multi views are being used. # It isn't therefore strictly an error as such as a subsequent view @@ -100,9 +99,7 @@ def view_handler_wrapper(wrapped, instance, args, kwargs): # set exception views to priority=1 so they won't take precedence over # the original view callable - transaction.set_transaction_name( - name, - priority=1 if args and isinstance(args[0], Exception) else 2) + transaction.set_transaction_name(name, priority=1 if args and isinstance(args[0], Exception) else 2) with FunctionTrace(name, source=view_callable) as trace: try: @@ -114,7 +111,7 @@ def view_handler_wrapper(wrapped, instance, args, kwargs): def wrap_view_handler(mapped_view): - if hasattr(mapped_view, '_nr_wrapped'): + if hasattr(mapped_view, "_nr_wrapped"): return mapped_view else: wrapped = FunctionWrapper(mapped_view, view_handler_wrapper) @@ -157,7 +154,7 @@ def _wrapper(context, request): return wrapper(context, request) finally: attr = instance.attr - inst = getattr(request, '__view__', None) + inst = getattr(request, "__view__", None) if inst is not None: if attr: handler = getattr(inst, attr) @@ -166,7 +163,7 @@ def _wrapper(context, request): tracer.name = name tracer.add_code_level_metrics(handler) else: - method = getattr(inst, '__call__') + method = getattr(inst, "__call__") if method: name = callable_name(method) transaction.set_transaction_name(name, priority=2) @@ -180,22 +177,21 @@ def instrument_pyramid_config_views(module): # Location of the ViewDeriver class changed from pyramid.config to # pyramid.config.views so check if present before trying to update. - if hasattr(module, 'ViewDeriver'): - wrap_out_function(module, 'ViewDeriver.__call__', wrap_view_handler) - elif hasattr(module, 'Configurator'): - wrap_out_function(module, 'Configurator._derive_view', - wrap_view_handler) + if hasattr(module, "ViewDeriver"): + wrap_out_function(module, "ViewDeriver.__call__", wrap_view_handler) + elif hasattr(module, "Configurator"): + wrap_out_function(module, "Configurator._derive_view", wrap_view_handler) - if hasattr(module, 'DefaultViewMapper'): + if hasattr(module, "DefaultViewMapper"): module.DefaultViewMapper.map_class_requestonly = FunctionWrapper( - module.DefaultViewMapper.map_class_requestonly, - default_view_mapper_wrapper) + module.DefaultViewMapper.map_class_requestonly, default_view_mapper_wrapper + ) module.DefaultViewMapper.map_class_native = FunctionWrapper( - module.DefaultViewMapper.map_class_native, - default_view_mapper_wrapper) + module.DefaultViewMapper.map_class_native, default_view_mapper_wrapper + ) def instrument_pyramid_config_tweens(module): - wrap_function_wrapper(module, 'Tweens.add_explicit', wrap_add_tween) + wrap_function_wrapper(module, "Tweens.add_explicit", wrap_add_tween) - wrap_function_wrapper(module, 'Tweens.add_implicit', wrap_add_tween) + wrap_function_wrapper(module, "Tweens.add_implicit", wrap_add_tween) diff --git a/tests/adapter_hypercorn/test_hypercorn.py b/tests/adapter_hypercorn/test_hypercorn.py index 8b53eee0ac..652dad0fc5 100644 --- a/tests/adapter_hypercorn/test_hypercorn.py +++ b/tests/adapter_hypercorn/test_hypercorn.py @@ -17,7 +17,6 @@ import time from urllib.request import HTTPError, urlopen -import pkg_resources import pytest from testing_support.fixtures import ( override_application_settings, @@ -39,8 +38,12 @@ from newrelic.api.transaction import ignore_transaction from newrelic.common.object_names import callable_name +from newrelic.common.package_version_utils import ( + get_package_version, + get_package_version_tuple, +) -HYPERCORN_VERSION = tuple(int(v) for v in pkg_resources.get_distribution("hypercorn").version.split(".")) +HYPERCORN_VERSION = get_package_version_tuple("hypercorn") asgi_2_unsupported = HYPERCORN_VERSION >= (0, 14, 1) wsgi_unsupported = HYPERCORN_VERSION < (0, 14, 1) @@ -132,7 +135,7 @@ def wait_for_port(port, retries=10): @override_application_settings({"transaction_name.naming_scheme": "framework"}) def test_hypercorn_200(port, app): - hypercorn_version = pkg_resources.get_distribution("hypercorn").version + hypercorn_version = get_package_version("hypercorn") @validate_transaction_metrics( callable_name(app), diff --git a/tests/framework_pyramid/test_append_slash_app.py b/tests/framework_pyramid/test_append_slash_app.py index f09e14b55d..bb865902c0 100644 --- a/tests/framework_pyramid/test_append_slash_app.py +++ b/tests/framework_pyramid/test_append_slash_app.py @@ -30,27 +30,21 @@ will have a count of 2. """ -import pkg_resources import pytest -import re +from testing_support.validators.validate_transaction_errors import ( + validate_transaction_errors, +) +from testing_support.validators.validate_transaction_metrics import ( + validate_transaction_metrics, +) -from testing_support.fixtures import override_application_settings -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics -from testing_support.validators.validate_transaction_errors import validate_transaction_errors - -def _to_int(version_str): - m = re.match(r'\d+', version_str) - return int(m.group(0)) if m else 0 - -def pyramid_version(): - s = pkg_resources.get_distribution('pyramid').version - return tuple([_to_int(c) for c in s.split('.')[:2]]) +from newrelic.common.package_version_utils import get_package_version_tuple # Defining a `pytestmark` at the module level means py.test will apply # this `skipif` conditional to all tests in the module. -pytestmark = pytest.mark.skipif(pyramid_version() < (1, 3), - reason='requires pyramid >= (1, 3)') +pytestmark = pytest.mark.skipif(get_package_version_tuple("pyramid") < (1, 3), reason="requires pyramid >= (1, 3)") + def target_application(): # We need to delay Pyramid application creation because of ordering @@ -62,35 +56,44 @@ def target_application(): # at global scope, so import it from a separate module. from _test_append_slash_app import _test_application + return _test_application + _test_append_slash_app_index_scoped_metrics = [ - ('Python/WSGI/Application', 1), - ('Python/WSGI/Response', 1), - ('Python/WSGI/Finalize', 1), - ('Function/pyramid.router:Router.__call__', 1), - ('Function/_test_append_slash_app:home_view', 1)] + ("Python/WSGI/Application", 1), + ("Python/WSGI/Response", 1), + ("Python/WSGI/Finalize", 1), + ("Function/pyramid.router:Router.__call__", 1), + ("Function/_test_append_slash_app:home_view", 1), +] + @validate_transaction_errors(errors=[]) -@validate_transaction_metrics('_test_append_slash_app:home_view', - scoped_metrics=_test_append_slash_app_index_scoped_metrics) +@validate_transaction_metrics( + "_test_append_slash_app:home_view", scoped_metrics=_test_append_slash_app_index_scoped_metrics +) def test_index(): application = target_application() - response = application.get('/') - response.mustcontain('INDEX RESPONSE') + response = application.get("/") + response.mustcontain("INDEX RESPONSE") + _test_not_found_append_slash_scoped_metrics = [ - ('Python/WSGI/Application', 1), - ('Python/WSGI/Response', 1), - ('Python/WSGI/Finalize', 1), - ('Function/pyramid.router:Router.__call__', 1), - ('Function/pyramid.view:AppendSlashNotFoundViewFactory', 1), - ('Function/_test_append_slash_app:not_found', 1)] + ("Python/WSGI/Application", 1), + ("Python/WSGI/Response", 1), + ("Python/WSGI/Finalize", 1), + ("Function/pyramid.router:Router.__call__", 1), + ("Function/pyramid.view:AppendSlashNotFoundViewFactory", 1), + ("Function/_test_append_slash_app:not_found", 1), +] + @validate_transaction_errors(errors=[]) -@validate_transaction_metrics('_test_append_slash_app:not_found', - scoped_metrics=_test_not_found_append_slash_scoped_metrics) +@validate_transaction_metrics( + "_test_append_slash_app:not_found", scoped_metrics=_test_not_found_append_slash_scoped_metrics +) def test_not_found_append_slash(): application = target_application() - response = application.get('/foo', status=404) - response.mustcontain('NOT FOUND') + response = application.get("/foo", status=404) + response.mustcontain("NOT FOUND") From 143e45adf0ac6098baad85ca60402acdc2f8df85 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Wed, 2 Aug 2023 15:45:27 -0700 Subject: [PATCH 2/6] Replace pkg_resources in wrapt/importer.py --- newrelic/packages/wrapt/importer.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/newrelic/packages/wrapt/importer.py b/newrelic/packages/wrapt/importer.py index 5c4d4cc663..1c7bbaa567 100644 --- a/newrelic/packages/wrapt/importer.py +++ b/newrelic/packages/wrapt/importer.py @@ -111,11 +111,16 @@ def import_hook(module): def discover_post_import_hooks(group): try: - import pkg_resources + # since Python 3.8 + from importlib.metadata import entry_points except ImportError: - return + try: + # Deprecated in Python 3.12 + from pkg_resources import iter_entry_points as entry_points + except ImportError: + return - for entrypoint in pkg_resources.iter_entry_points(group=group): + for entrypoint in entry_points(group=group): callback = _create_import_hook_from_entrypoint(entrypoint) register_post_import_hook(callback, entrypoint.name) From abcd6ebb2abf72a9616f6f0b730800fd85e3c722 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Wed, 16 Aug 2023 12:15:16 -0700 Subject: [PATCH 3/6] Add get_package_version from datastores --- tests/datastore_asyncpg/test_multiple_dbs.py | 9 +- tests/datastore_asyncpg/test_query.py | 3 +- tests/datastore_mysql/test_database.py | 236 ++++++++++------- tests/datastore_psycopg2cffi/test_database.py | 247 ++++++++++-------- 4 files changed, 277 insertions(+), 218 deletions(-) diff --git a/tests/datastore_asyncpg/test_multiple_dbs.py b/tests/datastore_asyncpg/test_multiple_dbs.py index a917a9e83d..60963c8ef7 100644 --- a/tests/datastore_asyncpg/test_multiple_dbs.py +++ b/tests/datastore_asyncpg/test_multiple_dbs.py @@ -12,20 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -import asyncio - import asyncpg import pytest from testing_support.db_settings import postgresql_settings from testing_support.fixtures import override_application_settings -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics from testing_support.util import instance_hostname +from testing_support.validators.validate_transaction_metrics import ( + validate_transaction_metrics, +) from newrelic.api.background_task import background_task +from newrelic.common.package_version_utils import get_package_version_tuple DB_MULTIPLE_SETTINGS = postgresql_settings() -ASYNCPG_VERSION = tuple(int(x) for x in getattr(asyncpg, "__version__", "0.0").split(".")[:2]) +ASYNCPG_VERSION = get_package_version_tuple("asyncpg") if ASYNCPG_VERSION < (0, 11): CONNECT_METRICS = [] diff --git a/tests/datastore_asyncpg/test_query.py b/tests/datastore_asyncpg/test_query.py index 838ced61da..0844cc2bd7 100644 --- a/tests/datastore_asyncpg/test_query.py +++ b/tests/datastore_asyncpg/test_query.py @@ -27,12 +27,13 @@ ) from newrelic.api.background_task import background_task +from newrelic.common.package_version_utils import get_package_version_tuple DB_SETTINGS = postgresql_settings()[0] PG_PREFIX = "Datastore/operation/Postgres/" -ASYNCPG_VERSION = tuple(int(x) for x in getattr(asyncpg, "__version__", "0.0").split(".")[:2]) +ASYNCPG_VERSION = get_package_version_tuple("asyncpg") if ASYNCPG_VERSION < (0, 11): CONNECT_METRICS = () diff --git a/tests/datastore_mysql/test_database.py b/tests/datastore_mysql/test_database.py index 2fc8ca129b..e0a9529585 100644 --- a/tests/datastore_mysql/test_database.py +++ b/tests/datastore_mysql/test_database.py @@ -13,94 +13,113 @@ # limitations under the License. import mysql.connector - -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics -from testing_support.validators.validate_database_trace_inputs import validate_database_trace_inputs - from testing_support.db_settings import mysql_settings +from testing_support.validators.validate_database_trace_inputs import ( + validate_database_trace_inputs, +) +from testing_support.validators.validate_transaction_metrics import ( + validate_transaction_metrics, +) + from newrelic.api.background_task import background_task +from newrelic.common.package_version_utils import get_package_version_tuple DB_SETTINGS = mysql_settings() DB_SETTINGS = DB_SETTINGS[0] DB_NAMESPACE = DB_SETTINGS["namespace"] DB_PROCEDURE = "hello_" + DB_NAMESPACE -mysql_version = tuple(int(x) for x in mysql.connector.__version__.split(".")[:3]) +mysql_version = get_package_version_tuple("mysql.connector") + if mysql_version >= (8, 0, 30): - _connector_metric_name = 'Function/mysql.connector.pooling:connect' + _connector_metric_name = "Function/mysql.connector.pooling:connect" else: - _connector_metric_name = 'Function/mysql.connector:connect' + _connector_metric_name = "Function/mysql.connector:connect" _test_execute_via_cursor_scoped_metrics = [ - (_connector_metric_name, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/select' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/insert' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/update' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/delete' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/drop', 2), - ('Datastore/operation/MySQL/create', 2), - ('Datastore/statement/MySQL/%s/call' % DB_PROCEDURE, 1), - ('Datastore/operation/MySQL/commit', 2), - ('Datastore/operation/MySQL/rollback', 1)] + (_connector_metric_name, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/select" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/insert" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/update" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/delete" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/drop", 2), + ("Datastore/operation/MySQL/create", 2), + ("Datastore/statement/MySQL/%s/call" % DB_PROCEDURE, 1), + ("Datastore/operation/MySQL/commit", 2), + ("Datastore/operation/MySQL/rollback", 1), +] _test_execute_via_cursor_rollup_metrics = [ - ('Datastore/all', 13), - ('Datastore/allOther', 13), - ('Datastore/MySQL/all', 13), - ('Datastore/MySQL/allOther', 13), - ('Datastore/operation/MySQL/select', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/select' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/insert', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/insert' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/update', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/update' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/delete', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/delete' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/%s/call' % DB_PROCEDURE, 1), - ('Datastore/operation/MySQL/call', 1), - ('Datastore/operation/MySQL/drop', 2), - ('Datastore/operation/MySQL/create', 2), - ('Datastore/operation/MySQL/commit', 2), - ('Datastore/operation/MySQL/rollback', 1)] - -@validate_transaction_metrics('test_database:test_execute_via_cursor', - scoped_metrics=_test_execute_via_cursor_scoped_metrics, - rollup_metrics=_test_execute_via_cursor_rollup_metrics, - background_task=True) + ("Datastore/all", 13), + ("Datastore/allOther", 13), + ("Datastore/MySQL/all", 13), + ("Datastore/MySQL/allOther", 13), + ("Datastore/operation/MySQL/select", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/select" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/insert", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/insert" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/update", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/update" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/delete", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/delete" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/%s/call" % DB_PROCEDURE, 1), + ("Datastore/operation/MySQL/call", 1), + ("Datastore/operation/MySQL/drop", 2), + ("Datastore/operation/MySQL/create", 2), + ("Datastore/operation/MySQL/commit", 2), + ("Datastore/operation/MySQL/rollback", 1), +] + + +@validate_transaction_metrics( + "test_database:test_execute_via_cursor", + scoped_metrics=_test_execute_via_cursor_scoped_metrics, + rollup_metrics=_test_execute_via_cursor_rollup_metrics, + background_task=True, +) @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_execute_via_cursor(table_name): - connection = mysql.connector.connect(db=DB_SETTINGS['name'], - user=DB_SETTINGS['user'], passwd=DB_SETTINGS['password'], - host=DB_SETTINGS['host'], port=DB_SETTINGS['port']) + connection = mysql.connector.connect( + db=DB_SETTINGS["name"], + user=DB_SETTINGS["user"], + passwd=DB_SETTINGS["password"], + host=DB_SETTINGS["host"], + port=DB_SETTINGS["port"], + ) cursor = connection.cursor() cursor.execute("""drop table if exists `%s`""" % table_name) - cursor.execute("""create table %s """ - """(a integer, b real, c text)""" % table_name) + cursor.execute("""create table %s """ """(a integer, b real, c text)""" % table_name) - cursor.executemany("""insert into `%s` """ % table_name + - """values (%(a)s, %(b)s, %(c)s)""", [dict(a=1, b=1.0, c='1.0'), - dict(a=2, b=2.2, c='2.2'), dict(a=3, b=3.3, c='3.3')]) + cursor.executemany( + """insert into `%s` """ % table_name + """values (%(a)s, %(b)s, %(c)s)""", + [{"a": 1, "b": 1.0, "c": "1.0"}, {"a": 2, "b": 2.2, "c": "2.2"}, {"a": 3, "b": 3.3, "c": "3.3"}], + ) cursor.execute("""select * from %s""" % table_name) - for row in cursor: pass + for row in cursor: + pass - cursor.execute("""update `%s` """ % table_name + - """set a=%(a)s, b=%(b)s, c=%(c)s where a=%(old_a)s""", - dict(a=4, b=4.0, c='4.0', old_a=1)) + cursor.execute( + """update `%s` """ % table_name + """set a=%(a)s, b=%(b)s, c=%(c)s where a=%(old_a)s""", + {"a": 4, "b": 4.0, "c": "4.0", "old_a": 1}, + ) cursor.execute("""delete from `%s` where a=2""" % table_name) cursor.execute("""drop procedure if exists %s""" % DB_PROCEDURE) - cursor.execute("""CREATE PROCEDURE %s() + cursor.execute( + """CREATE PROCEDURE %s() BEGIN SELECT 'Hello World!'; - END""" % DB_PROCEDURE) + END""" + % DB_PROCEDURE + ) cursor.callproc("%s" % DB_PROCEDURE) @@ -108,76 +127,91 @@ def test_execute_via_cursor(table_name): connection.rollback() connection.commit() + _test_connect_using_alias_scoped_metrics = [ - (_connector_metric_name, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/select' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/insert' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/update' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/delete' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/drop', 2), - ('Datastore/operation/MySQL/create', 2), - ('Datastore/statement/MySQL/%s/call' % DB_PROCEDURE, 1), - ('Datastore/operation/MySQL/commit', 2), - ('Datastore/operation/MySQL/rollback', 1)] + (_connector_metric_name, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/select" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/insert" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/update" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/delete" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/drop", 2), + ("Datastore/operation/MySQL/create", 2), + ("Datastore/statement/MySQL/%s/call" % DB_PROCEDURE, 1), + ("Datastore/operation/MySQL/commit", 2), + ("Datastore/operation/MySQL/rollback", 1), +] _test_connect_using_alias_rollup_metrics = [ - ('Datastore/all', 13), - ('Datastore/allOther', 13), - ('Datastore/MySQL/all', 13), - ('Datastore/MySQL/allOther', 13), - ('Datastore/operation/MySQL/select', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/select' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/insert', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/insert' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/update', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/update' % DB_NAMESPACE, 1), - ('Datastore/operation/MySQL/delete', 1), - ('Datastore/statement/MySQL/datastore_mysql_%s/delete' % DB_NAMESPACE, 1), - ('Datastore/statement/MySQL/%s/call' % DB_PROCEDURE, 1), - ('Datastore/operation/MySQL/call', 1), - ('Datastore/operation/MySQL/drop', 2), - ('Datastore/operation/MySQL/create', 2), - ('Datastore/operation/MySQL/commit', 2), - ('Datastore/operation/MySQL/rollback', 1)] - -@validate_transaction_metrics('test_database:test_connect_using_alias', - scoped_metrics=_test_connect_using_alias_scoped_metrics, - rollup_metrics=_test_connect_using_alias_rollup_metrics, - background_task=True) + ("Datastore/all", 13), + ("Datastore/allOther", 13), + ("Datastore/MySQL/all", 13), + ("Datastore/MySQL/allOther", 13), + ("Datastore/operation/MySQL/select", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/select" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/insert", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/insert" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/update", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/update" % DB_NAMESPACE, 1), + ("Datastore/operation/MySQL/delete", 1), + ("Datastore/statement/MySQL/datastore_mysql_%s/delete" % DB_NAMESPACE, 1), + ("Datastore/statement/MySQL/%s/call" % DB_PROCEDURE, 1), + ("Datastore/operation/MySQL/call", 1), + ("Datastore/operation/MySQL/drop", 2), + ("Datastore/operation/MySQL/create", 2), + ("Datastore/operation/MySQL/commit", 2), + ("Datastore/operation/MySQL/rollback", 1), +] + + +@validate_transaction_metrics( + "test_database:test_connect_using_alias", + scoped_metrics=_test_connect_using_alias_scoped_metrics, + rollup_metrics=_test_connect_using_alias_rollup_metrics, + background_task=True, +) @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_connect_using_alias(table_name): - connection = mysql.connector.connect(db=DB_SETTINGS['name'], - user=DB_SETTINGS['user'], passwd=DB_SETTINGS['password'], - host=DB_SETTINGS['host'], port=DB_SETTINGS['port']) + connection = mysql.connector.connect( + db=DB_SETTINGS["name"], + user=DB_SETTINGS["user"], + passwd=DB_SETTINGS["password"], + host=DB_SETTINGS["host"], + port=DB_SETTINGS["port"], + ) cursor = connection.cursor() cursor.execute("""drop table if exists `%s`""" % table_name) - cursor.execute("""create table %s """ - """(a integer, b real, c text)""" % table_name) + cursor.execute("""create table %s """ """(a integer, b real, c text)""" % table_name) - cursor.executemany("""insert into `%s` """ % table_name + - """values (%(a)s, %(b)s, %(c)s)""", [dict(a=1, b=1.0, c='1.0'), - dict(a=2, b=2.2, c='2.2'), dict(a=3, b=3.3, c='3.3')]) + cursor.executemany( + """insert into `%s` """ % table_name + """values (%(a)s, %(b)s, %(c)s)""", + [{"a": 1, "b": 1.0, "c": "1.0"}, {"a": 2, "b": 2.2, "c": "2.2"}, {"a": 3, "b": 3.3, "c": "3.3"}], + ) cursor.execute("""select * from %s""" % table_name) - for row in cursor: pass + for row in cursor: + pass - cursor.execute("""update `%s` """ % table_name + - """set a=%(a)s, b=%(b)s, c=%(c)s where a=%(old_a)s""", - dict(a=4, b=4.0, c='4.0', old_a=1)) + cursor.execute( + """update `%s` """ % table_name + """set a=%(a)s, b=%(b)s, c=%(c)s where a=%(old_a)s""", + {"a": 4, "b": 4.0, "c": "4.0", "old_a": 1}, + ) cursor.execute("""delete from `%s` where a=2""" % table_name) cursor.execute("""drop procedure if exists %s""" % DB_PROCEDURE) - cursor.execute("""CREATE PROCEDURE %s() + cursor.execute( + """CREATE PROCEDURE %s() BEGIN SELECT 'Hello World!'; - END""" % DB_PROCEDURE) + END""" + % DB_PROCEDURE + ) cursor.callproc("%s" % DB_PROCEDURE) diff --git a/tests/datastore_psycopg2cffi/test_database.py b/tests/datastore_psycopg2cffi/test_database.py index 54ff6ad09d..82680a767b 100644 --- a/tests/datastore_psycopg2cffi/test_database.py +++ b/tests/datastore_psycopg2cffi/test_database.py @@ -15,166 +15,188 @@ import psycopg2cffi import psycopg2cffi.extensions import psycopg2cffi.extras - -from testing_support.fixtures import validate_stats_engine_explain_plan_output_is_none -from testing_support.validators.validate_transaction_errors import validate_transaction_errors -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics -from testing_support.validators.validate_transaction_slow_sql_count import \ - validate_transaction_slow_sql_count -from testing_support.validators.validate_database_trace_inputs import validate_database_trace_inputs - from testing_support.db_settings import postgresql_settings +from testing_support.fixtures import validate_stats_engine_explain_plan_output_is_none +from testing_support.validators.validate_database_trace_inputs import ( + validate_database_trace_inputs, +) +from testing_support.validators.validate_transaction_errors import ( + validate_transaction_errors, +) +from testing_support.validators.validate_transaction_metrics import ( + validate_transaction_metrics, +) +from testing_support.validators.validate_transaction_slow_sql_count import ( + validate_transaction_slow_sql_count, +) from newrelic.api.background_task import background_task +from newrelic.common.package_version_utils import get_package_version_tuple DB_SETTINGS = postgresql_settings()[0] _test_execute_via_cursor_scoped_metrics = [ - ('Function/psycopg2cffi:connect', 1), - ('Function/psycopg2cffi._impl.connection:Connection.__enter__', 1), - ('Function/psycopg2cffi._impl.connection:Connection.__exit__', 1), - ('Datastore/statement/Postgres/%s/select' % DB_SETTINGS["table_name"], 1), - ('Datastore/statement/Postgres/%s/insert' % DB_SETTINGS["table_name"], 1), - ('Datastore/statement/Postgres/%s/update' % DB_SETTINGS["table_name"], 1), - ('Datastore/statement/Postgres/%s/delete' % DB_SETTINGS["table_name"], 1), - ('Datastore/statement/Postgres/now/call', 1), - ('Datastore/statement/Postgres/pg_sleep/call', 1), - ('Datastore/operation/Postgres/drop', 1), - ('Datastore/operation/Postgres/create', 1), - ('Datastore/operation/Postgres/commit', 3), - ('Datastore/operation/Postgres/rollback', 1)] + ("Function/psycopg2cffi:connect", 1), + ("Function/psycopg2cffi._impl.connection:Connection.__enter__", 1), + ("Function/psycopg2cffi._impl.connection:Connection.__exit__", 1), + ("Datastore/statement/Postgres/%s/select" % DB_SETTINGS["table_name"], 1), + ("Datastore/statement/Postgres/%s/insert" % DB_SETTINGS["table_name"], 1), + ("Datastore/statement/Postgres/%s/update" % DB_SETTINGS["table_name"], 1), + ("Datastore/statement/Postgres/%s/delete" % DB_SETTINGS["table_name"], 1), + ("Datastore/statement/Postgres/now/call", 1), + ("Datastore/statement/Postgres/pg_sleep/call", 1), + ("Datastore/operation/Postgres/drop", 1), + ("Datastore/operation/Postgres/create", 1), + ("Datastore/operation/Postgres/commit", 3), + ("Datastore/operation/Postgres/rollback", 1), +] _test_execute_via_cursor_rollup_metrics = [ - ('Datastore/all', 13), - ('Datastore/allOther', 13), - ('Datastore/Postgres/all', 13), - ('Datastore/Postgres/allOther', 13), - ('Datastore/operation/Postgres/select', 1), - ('Datastore/statement/Postgres/%s/select' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/insert', 1), - ('Datastore/statement/Postgres/%s/insert' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/update', 1), - ('Datastore/statement/Postgres/%s/update' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/delete', 1), - ('Datastore/statement/Postgres/%s/delete' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/drop', 1), - ('Datastore/operation/Postgres/create', 1), - ('Datastore/statement/Postgres/now/call', 1), - ('Datastore/statement/Postgres/pg_sleep/call', 1), - ('Datastore/operation/Postgres/call', 2), - ('Datastore/operation/Postgres/commit', 3), - ('Datastore/operation/Postgres/rollback', 1)] - - -@validate_transaction_metrics('test_database:test_execute_via_cursor', - scoped_metrics=_test_execute_via_cursor_scoped_metrics, - rollup_metrics=_test_execute_via_cursor_rollup_metrics, - background_task=True) + ("Datastore/all", 13), + ("Datastore/allOther", 13), + ("Datastore/Postgres/all", 13), + ("Datastore/Postgres/allOther", 13), + ("Datastore/operation/Postgres/select", 1), + ("Datastore/statement/Postgres/%s/select" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/insert", 1), + ("Datastore/statement/Postgres/%s/insert" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/update", 1), + ("Datastore/statement/Postgres/%s/update" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/delete", 1), + ("Datastore/statement/Postgres/%s/delete" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/drop", 1), + ("Datastore/operation/Postgres/create", 1), + ("Datastore/statement/Postgres/now/call", 1), + ("Datastore/statement/Postgres/pg_sleep/call", 1), + ("Datastore/operation/Postgres/call", 2), + ("Datastore/operation/Postgres/commit", 3), + ("Datastore/operation/Postgres/rollback", 1), +] + + +@validate_transaction_metrics( + "test_database:test_execute_via_cursor", + scoped_metrics=_test_execute_via_cursor_scoped_metrics, + rollup_metrics=_test_execute_via_cursor_rollup_metrics, + background_task=True, +) @validate_database_trace_inputs(sql_parameters_type=tuple) @background_task() def test_execute_via_cursor(): with psycopg2cffi.connect( - database=DB_SETTINGS['name'], user=DB_SETTINGS['user'], - password=DB_SETTINGS['password'], host=DB_SETTINGS['host'], - port=DB_SETTINGS['port']) as connection: + database=DB_SETTINGS["name"], + user=DB_SETTINGS["user"], + password=DB_SETTINGS["password"], + host=DB_SETTINGS["host"], + port=DB_SETTINGS["port"], + ) as connection: cursor = connection.cursor() psycopg2cffi.extensions.register_type(psycopg2cffi.extensions.UNICODE) - psycopg2cffi.extensions.register_type( - psycopg2cffi.extensions.UNICODE, - connection) - psycopg2cffi.extensions.register_type( - psycopg2cffi.extensions.UNICODE, - cursor) + psycopg2cffi.extensions.register_type(psycopg2cffi.extensions.UNICODE, connection) + psycopg2cffi.extensions.register_type(psycopg2cffi.extensions.UNICODE, cursor) cursor.execute("""drop table if exists %s""" % DB_SETTINGS["table_name"]) - cursor.execute("""create table %s """ % DB_SETTINGS["table_name"] + - """(a integer, b real, c text)""") + cursor.execute("""create table %s """ % DB_SETTINGS["table_name"] + """(a integer, b real, c text)""") - cursor.executemany("""insert into %s """ % DB_SETTINGS["table_name"] + - """values (%s, %s, %s)""", [(1, 1.0, '1.0'), - (2, 2.2, '2.2'), (3, 3.3, '3.3')]) + cursor.executemany( + """insert into %s """ % DB_SETTINGS["table_name"] + """values (%s, %s, %s)""", + [(1, 1.0, "1.0"), (2, 2.2, "2.2"), (3, 3.3, "3.3")], + ) cursor.execute("""select * from %s""" % DB_SETTINGS["table_name"]) for row in cursor: pass - cursor.execute("""update %s""" % DB_SETTINGS["table_name"] + """ set a=%s, b=%s, """ - """c=%s where a=%s""", (4, 4.0, '4.0', 1)) + cursor.execute( + """update %s""" % DB_SETTINGS["table_name"] + """ set a=%s, b=%s, """ """c=%s where a=%s""", + (4, 4.0, "4.0", 1), + ) cursor.execute("""delete from %s where a=2""" % DB_SETTINGS["table_name"]) connection.commit() - cursor.callproc('now') - cursor.callproc('pg_sleep', (0,)) + cursor.callproc("now") + cursor.callproc("pg_sleep", (0,)) connection.rollback() connection.commit() _test_rollback_on_exception_scoped_metrics = [ - ('Function/psycopg2cffi:connect', 1), - ('Function/psycopg2cffi._impl.connection:Connection.__enter__', 1), - ('Function/psycopg2cffi._impl.connection:Connection.__exit__', 1), - ('Datastore/operation/Postgres/rollback', 1)] + ("Function/psycopg2cffi:connect", 1), + ("Function/psycopg2cffi._impl.connection:Connection.__enter__", 1), + ("Function/psycopg2cffi._impl.connection:Connection.__exit__", 1), + ("Datastore/operation/Postgres/rollback", 1), +] _test_rollback_on_exception_rollup_metrics = [ - ('Datastore/all', 2), - ('Datastore/allOther', 2), - ('Datastore/Postgres/all', 2), - ('Datastore/Postgres/allOther', 2)] - - -@validate_transaction_metrics('test_database:test_rollback_on_exception', - scoped_metrics=_test_rollback_on_exception_scoped_metrics, - rollup_metrics=_test_rollback_on_exception_rollup_metrics, - background_task=True) + ("Datastore/all", 2), + ("Datastore/allOther", 2), + ("Datastore/Postgres/all", 2), + ("Datastore/Postgres/allOther", 2), +] + + +@validate_transaction_metrics( + "test_database:test_rollback_on_exception", + scoped_metrics=_test_rollback_on_exception_scoped_metrics, + rollup_metrics=_test_rollback_on_exception_rollup_metrics, + background_task=True, +) @validate_database_trace_inputs(sql_parameters_type=tuple) @background_task() def test_rollback_on_exception(): try: with psycopg2cffi.connect( - database=DB_SETTINGS['name'], user=DB_SETTINGS['user'], - password=DB_SETTINGS['password'], host=DB_SETTINGS['host'], - port=DB_SETTINGS['port']): - - raise RuntimeError('error') + database=DB_SETTINGS["name"], + user=DB_SETTINGS["user"], + password=DB_SETTINGS["password"], + host=DB_SETTINGS["host"], + port=DB_SETTINGS["port"], + ): + + raise RuntimeError("error") except RuntimeError: pass _test_async_mode_scoped_metrics = [ - ('Function/psycopg2cffi:connect', 1), - ('Datastore/statement/Postgres/%s/select' % DB_SETTINGS["table_name"], 1), - ('Datastore/statement/Postgres/%s/insert' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/drop', 1), - ('Datastore/operation/Postgres/create', 1)] + ("Function/psycopg2cffi:connect", 1), + ("Datastore/statement/Postgres/%s/select" % DB_SETTINGS["table_name"], 1), + ("Datastore/statement/Postgres/%s/insert" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/drop", 1), + ("Datastore/operation/Postgres/create", 1), +] _test_async_mode_rollup_metrics = [ - ('Datastore/all', 5), - ('Datastore/allOther', 5), - ('Datastore/Postgres/all', 5), - ('Datastore/Postgres/allOther', 5), - ('Datastore/operation/Postgres/select', 1), - ('Datastore/statement/Postgres/%s/select' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/insert', 1), - ('Datastore/statement/Postgres/%s/insert' % DB_SETTINGS["table_name"], 1), - ('Datastore/operation/Postgres/drop', 1), - ('Datastore/operation/Postgres/create', 1)] + ("Datastore/all", 5), + ("Datastore/allOther", 5), + ("Datastore/Postgres/all", 5), + ("Datastore/Postgres/allOther", 5), + ("Datastore/operation/Postgres/select", 1), + ("Datastore/statement/Postgres/%s/select" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/insert", 1), + ("Datastore/statement/Postgres/%s/insert" % DB_SETTINGS["table_name"], 1), + ("Datastore/operation/Postgres/drop", 1), + ("Datastore/operation/Postgres/create", 1), +] @validate_stats_engine_explain_plan_output_is_none() @validate_transaction_slow_sql_count(num_slow_sql=4) @validate_database_trace_inputs(sql_parameters_type=tuple) -@validate_transaction_metrics('test_database:test_async_mode', - scoped_metrics=_test_async_mode_scoped_metrics, - rollup_metrics=_test_async_mode_rollup_metrics, - background_task=True) +@validate_transaction_metrics( + "test_database:test_async_mode", + scoped_metrics=_test_async_mode_scoped_metrics, + rollup_metrics=_test_async_mode_rollup_metrics, + background_task=True, +) @validate_transaction_errors(errors=[]) @background_task() def test_async_mode(): @@ -182,16 +204,19 @@ def test_async_mode(): wait = psycopg2cffi.extras.wait_select kwargs = {} - version = tuple(int(_) for _ in psycopg2cffi.__version__.split('.')) + version = get_package_version_tuple("psycopg2cffi") if version >= (2, 8): - kwargs['async_'] = 1 + kwargs["async_"] = 1 else: - kwargs['async'] = 1 + kwargs["async"] = 1 async_conn = psycopg2cffi.connect( - database=DB_SETTINGS['name'], user=DB_SETTINGS['user'], - password=DB_SETTINGS['password'], host=DB_SETTINGS['host'], - port=DB_SETTINGS['port'], **kwargs + database=DB_SETTINGS["name"], + user=DB_SETTINGS["user"], + password=DB_SETTINGS["password"], + host=DB_SETTINGS["host"], + port=DB_SETTINGS["port"], + **kwargs ) wait(async_conn) async_cur = async_conn.cursor() @@ -199,12 +224,10 @@ def test_async_mode(): async_cur.execute("""drop table if exists %s""" % DB_SETTINGS["table_name"]) wait(async_cur.connection) - async_cur.execute("""create table %s """ % DB_SETTINGS["table_name"] + - """(a integer, b real, c text)""") + async_cur.execute("""create table %s """ % DB_SETTINGS["table_name"] + """(a integer, b real, c text)""") wait(async_cur.connection) - async_cur.execute("""insert into %s """ % DB_SETTINGS["table_name"] + - """values (%s, %s, %s)""", (1, 1.0, '1.0')) + async_cur.execute("""insert into %s """ % DB_SETTINGS["table_name"] + """values (%s, %s, %s)""", (1, 1.0, "1.0")) wait(async_cur.connection) async_cur.execute("""select * from %s""" % DB_SETTINGS["table_name"]) From 2e8aa5c95cf0dac417d28e74282318dccfbca80a Mon Sep 17 00:00:00 2001 From: lrafeei Date: Thu, 17 Aug 2023 00:04:52 +0000 Subject: [PATCH 4/6] [Mega-Linter] Apply linters fixes --- tests/datastore_asyncpg/test_multiple_dbs.py | 1 - tests/datastore_mysql/test_database.py | 2 -- tests/datastore_psycopg2cffi/test_database.py | 3 --- 3 files changed, 6 deletions(-) diff --git a/tests/datastore_asyncpg/test_multiple_dbs.py b/tests/datastore_asyncpg/test_multiple_dbs.py index 60963c8ef7..2b14cc7b96 100644 --- a/tests/datastore_asyncpg/test_multiple_dbs.py +++ b/tests/datastore_asyncpg/test_multiple_dbs.py @@ -101,7 +101,6 @@ async def _exercise_db(): - postgresql1 = DB_MULTIPLE_SETTINGS[0] postgresql2 = DB_MULTIPLE_SETTINGS[1] diff --git a/tests/datastore_mysql/test_database.py b/tests/datastore_mysql/test_database.py index e0a9529585..df9eedd0f2 100644 --- a/tests/datastore_mysql/test_database.py +++ b/tests/datastore_mysql/test_database.py @@ -80,7 +80,6 @@ @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_execute_via_cursor(table_name): - connection = mysql.connector.connect( db=DB_SETTINGS["name"], user=DB_SETTINGS["user"], @@ -172,7 +171,6 @@ def test_execute_via_cursor(table_name): @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_connect_using_alias(table_name): - connection = mysql.connector.connect( db=DB_SETTINGS["name"], user=DB_SETTINGS["user"], diff --git a/tests/datastore_psycopg2cffi/test_database.py b/tests/datastore_psycopg2cffi/test_database.py index 82680a767b..39a4d0a01e 100644 --- a/tests/datastore_psycopg2cffi/test_database.py +++ b/tests/datastore_psycopg2cffi/test_database.py @@ -90,7 +90,6 @@ def test_execute_via_cursor(): host=DB_SETTINGS["host"], port=DB_SETTINGS["port"], ) as connection: - cursor = connection.cursor() psycopg2cffi.extensions.register_type(psycopg2cffi.extensions.UNICODE) @@ -160,7 +159,6 @@ def test_rollback_on_exception(): host=DB_SETTINGS["host"], port=DB_SETTINGS["port"], ): - raise RuntimeError("error") except RuntimeError: pass @@ -200,7 +198,6 @@ def test_rollback_on_exception(): @validate_transaction_errors(errors=[]) @background_task() def test_async_mode(): - wait = psycopg2cffi.extras.wait_select kwargs = {} From 1d056cd5a16a53302bf8f25e61e1707a304b7aa7 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Wed, 16 Aug 2023 17:31:22 -0700 Subject: [PATCH 5/6] Push empty commit From 867a7dcca97a0df0a30859aa91e0c19f78e15272 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Fri, 18 Aug 2023 16:15:32 -0700 Subject: [PATCH 6/6] Add assert statements for version --- tests/datastore_asyncpg/test_multiple_dbs.py | 2 ++ tests/datastore_asyncpg/test_query.py | 9 +++++++++ tests/datastore_mysql/test_database.py | 2 ++ tests/datastore_psycopg2cffi/test_database.py | 1 + 4 files changed, 14 insertions(+) diff --git a/tests/datastore_asyncpg/test_multiple_dbs.py b/tests/datastore_asyncpg/test_multiple_dbs.py index 2b14cc7b96..9d7a3de95e 100644 --- a/tests/datastore_asyncpg/test_multiple_dbs.py +++ b/tests/datastore_asyncpg/test_multiple_dbs.py @@ -145,6 +145,7 @@ async def _exercise_db(): ) @background_task() def test_multiple_databases_enable_instance(event_loop): + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(_exercise_db()) @@ -161,4 +162,5 @@ def test_multiple_databases_enable_instance(event_loop): ) @background_task() def test_multiple_databases_disable_instance(event_loop): + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(_exercise_db()) diff --git a/tests/datastore_asyncpg/test_query.py b/tests/datastore_asyncpg/test_query.py index 0844cc2bd7..6deb7ca9a8 100644 --- a/tests/datastore_asyncpg/test_query.py +++ b/tests/datastore_asyncpg/test_query.py @@ -66,6 +66,7 @@ def conn(event_loop): @background_task(name="test_single") @pytest.mark.parametrize("method", ("execute",)) def test_single(event_loop, method, conn): + assert ASYNCPG_VERSION is not None _method = getattr(conn, method) event_loop.run_until_complete(_method("""SELECT 0""")) @@ -82,6 +83,7 @@ def test_single(event_loop, method, conn): @background_task(name="test_prepared_single") @pytest.mark.parametrize("method", ("fetch", "fetchrow", "fetchval")) def test_prepared_single(event_loop, method, conn): + assert ASYNCPG_VERSION is not None _method = getattr(conn, method) event_loop.run_until_complete(_method("""SELECT 0""")) @@ -94,6 +96,7 @@ def test_prepared_single(event_loop, method, conn): ) @background_task(name="test_prepare") def test_prepare(event_loop, conn): + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(conn.prepare("""SELECT 0""")) @@ -126,6 +129,7 @@ async def amain(): # 2 statements await conn.copy_from_query("""SELECT 0""", output=BytesIO()) + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(amain()) @@ -140,6 +144,7 @@ async def amain(): ) @background_task(name="test_select_many") def test_select_many(event_loop, conn): + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(conn.executemany("""SELECT $1::int""", ((1,), (2,)))) @@ -159,6 +164,7 @@ async def amain(): async with conn.transaction(): await conn.execute("""SELECT 0""") + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(amain()) @@ -182,6 +188,7 @@ async def amain(): await conn.cursor("SELECT 0") + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(amain()) @@ -201,6 +208,7 @@ async def amain(): ) @background_task(name="test_unix_socket_connect") def test_unix_socket_connect(event_loop): + assert ASYNCPG_VERSION is not None with pytest.raises(OSError): event_loop.run_until_complete(asyncpg.connect("postgres://?host=/.s.PGSQL.THIS_FILE_BETTER_NOT_EXIST")) @@ -234,4 +242,5 @@ async def amain(): finally: await pool.close() + assert ASYNCPG_VERSION is not None event_loop.run_until_complete(amain()) diff --git a/tests/datastore_mysql/test_database.py b/tests/datastore_mysql/test_database.py index df9eedd0f2..bd45b1d902 100644 --- a/tests/datastore_mysql/test_database.py +++ b/tests/datastore_mysql/test_database.py @@ -80,6 +80,7 @@ @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_execute_via_cursor(table_name): + assert mysql_version is not None connection = mysql.connector.connect( db=DB_SETTINGS["name"], user=DB_SETTINGS["user"], @@ -171,6 +172,7 @@ def test_execute_via_cursor(table_name): @validate_database_trace_inputs(sql_parameters_type=dict) @background_task() def test_connect_using_alias(table_name): + assert mysql_version is not None connection = mysql.connector.connect( db=DB_SETTINGS["name"], user=DB_SETTINGS["user"], diff --git a/tests/datastore_psycopg2cffi/test_database.py b/tests/datastore_psycopg2cffi/test_database.py index 39a4d0a01e..86ecb60be3 100644 --- a/tests/datastore_psycopg2cffi/test_database.py +++ b/tests/datastore_psycopg2cffi/test_database.py @@ -202,6 +202,7 @@ def test_async_mode(): kwargs = {} version = get_package_version_tuple("psycopg2cffi") + assert version is not None if version >= (2, 8): kwargs["async_"] = 1 else: