diff --git a/tests/datastore_aredis/test_custom_conn_pool.py b/tests/datastore_aredis/test_custom_conn_pool.py new file mode 100644 index 0000000000..3441544120 --- /dev/null +++ b/tests/datastore_aredis/test_custom_conn_pool.py @@ -0,0 +1,151 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +''' The purpose of these tests is to confirm that using a non-standard +connection pool that does not have a `connection_kwargs` attribute +will not result in an error. +''' + +import pytest +import aredis + +from newrelic.api.background_task import background_task + +from testing_support.fixture.event_loop import event_loop as loop +from testing_support.fixtures import (validate_transaction_metrics, + override_application_settings) +from testing_support.db_settings import redis_settings +from testing_support.util import instance_hostname + +DB_SETTINGS = redis_settings()[0] +REDIS_PY_VERSION = aredis.VERSION + + +class FakeConnectionPool(object): + """Connection Pool without connection_kwargs attribute.""" + + def __init__(self, connection): + self.connection = connection + + def get_connection(self, name=None, *keys, **options): + return self.connection + + def release(self, connection): + self.connection.disconnect() + +# Settings + +_enable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': True, +} +_disable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': False, +} + +# Metrics + +# We don't record instance metrics when using redis blaster, +# so we just check for base metrics. + +_base_scoped_metrics = ( + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/set', 1), + ('Datastore/operation/Redis/client_list', 1), +) + +_base_rollup_metrics = ( + ('Datastore/all', 3), + ('Datastore/allOther', 3), + ('Datastore/Redis/all', 3), + ('Datastore/Redis/allOther', 3), + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/set', 1), + ('Datastore/operation/Redis/client_list', 1), +) + +_disable_scoped_metrics = list(_base_scoped_metrics) +_disable_rollup_metrics = list(_base_rollup_metrics) + +_enable_scoped_metrics = list(_base_scoped_metrics) +_enable_rollup_metrics = list(_base_rollup_metrics) + +_host = instance_hostname(DB_SETTINGS['host']) +_port = DB_SETTINGS['port'] + +_instance_metric_name = 'Datastore/instance/Redis/%s/%s' % (_host, _port) + +_enable_rollup_metrics.append( + (_instance_metric_name, 3) +) + +_disable_rollup_metrics.append( + (_instance_metric_name, None) +) + +# Operations + +async def exercise_redis(client): + await client.set('key', 'value') + await client.get('key') + await client.execute_command('CLIENT', 'LIST', parse='LIST') + +# Tests + +@override_application_settings(_enable_instance_settings) +@validate_transaction_metrics( + 'test_custom_conn_pool:test_fake_conn_pool_enable_instance', + scoped_metrics=_enable_scoped_metrics, + rollup_metrics=_enable_rollup_metrics, + background_task=True) +@background_task() +def test_fake_conn_pool_enable_instance(loop): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + + # Get a real connection + + conn = client.connection_pool.get_connection('GET') + + # Replace the original connection pool with one that doesn't + # have the `connection_kwargs` attribute. + + fake_pool = FakeConnectionPool(conn) + client.connection_pool = fake_pool + assert not hasattr(client.connection_pool, 'connection_kwargs') + + loop.run_until_complete(exercise_redis(client)) + +@override_application_settings(_disable_instance_settings) +@validate_transaction_metrics( + 'test_custom_conn_pool:test_fake_conn_pool_disable_instance', + scoped_metrics=_disable_scoped_metrics, + rollup_metrics=_disable_rollup_metrics, + background_task=True) +@background_task() +def test_fake_conn_pool_disable_instance(loop): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + + # Get a real connection + + conn = client.connection_pool.get_connection('GET') + + # Replace the original connection pool with one that doesn't + # have the `connection_kwargs` attribute. + + fake_pool = FakeConnectionPool(conn) + client.connection_pool = fake_pool + assert not hasattr(client.connection_pool, 'connection_kwargs') + + loop.run_until_complete(exercise_redis(client)) diff --git a/tests/datastore_aredis/test_execute_command.py b/tests/datastore_aredis/test_execute_command.py index 0531c75736..7db3c9c59a 100644 --- a/tests/datastore_aredis/test_execute_command.py +++ b/tests/datastore_aredis/test_execute_command.py @@ -86,4 +86,40 @@ def test_strict_redis_execute_command_two_args_enable(loop): r = aredis.StrictRedis(host=DB_SETTINGS['host'], port=DB_SETTINGS['port'], db=0) loop.run_until_complete(exercise_redis_multi_args(r)) - \ No newline at end of file + +@override_application_settings(_disable_instance_settings) +@validate_transaction_metrics( + 'test_execute_command:test_strict_redis_execute_command_two_args_disabled', + scoped_metrics=_disable_scoped_metrics, + rollup_metrics=_disable_rollup_metrics, + background_task=True) +@background_task() +def test_strict_redis_execute_command_two_args_disabled(loop): + r = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + loop.run_until_complete(exercise_redis_multi_args(r)) + + +@override_application_settings(_enable_instance_settings) +@validate_transaction_metrics( + 'test_execute_command:test_strict_redis_execute_command_as_one_arg_enable', + scoped_metrics=_enable_scoped_metrics, + rollup_metrics=_enable_rollup_metrics, + background_task=True) +@background_task() +def test_strict_redis_execute_command_as_one_arg_enable(loop): + r = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + loop.run_until_complete(exercise_redis_single_arg(r)) + +@override_application_settings(_disable_instance_settings) +@validate_transaction_metrics( + 'test_execute_command:test_strict_redis_execute_command_as_one_arg_disabled', + scoped_metrics=_disable_scoped_metrics, + rollup_metrics=_disable_rollup_metrics, + background_task=True) +@background_task() +def test_strict_redis_execute_command_as_one_arg_disabled(loop): + r = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + loop.run_until_complete(exercise_redis_single_arg(r)) diff --git a/tests/datastore_aredis/test_get_and_set.py b/tests/datastore_aredis/test_get_and_set.py new file mode 100644 index 0000000000..fbde29d867 --- /dev/null +++ b/tests/datastore_aredis/test_get_and_set.py @@ -0,0 +1,101 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import aredis + +from newrelic.api.background_task import background_task + +from testing_support.fixture.event_loop import event_loop as loop +from testing_support.fixtures import (validate_transaction_metrics, + override_application_settings) +from testing_support.db_settings import redis_settings +from testing_support.util import instance_hostname + +DB_SETTINGS = redis_settings()[0] + +# Settings + +_enable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': True, +} +_disable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': False, +} + +# Metrics + +_base_scoped_metrics = ( + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/set', 1), +) + +_base_rollup_metrics = ( + ('Datastore/all', 2), + ('Datastore/allOther', 2), + ('Datastore/Redis/all', 2), + ('Datastore/Redis/allOther', 2), + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/set', 1), +) + +_disable_scoped_metrics = list(_base_scoped_metrics) +_disable_rollup_metrics = list(_base_rollup_metrics) + +_enable_scoped_metrics = list(_base_scoped_metrics) +_enable_rollup_metrics = list(_base_rollup_metrics) + +_host = instance_hostname(DB_SETTINGS['host']) +_port = DB_SETTINGS['port'] + +_instance_metric_name = 'Datastore/instance/Redis/%s/%s' % (_host, _port) + +_enable_rollup_metrics.append( + (_instance_metric_name, 2) +) + +_disable_rollup_metrics.append( + (_instance_metric_name, None) +) + +# Operations + +async def exercise_redis(client): + await client.set('key', 'value') + await client.get('key') + +# Tests + +@override_application_settings(_enable_instance_settings) +@validate_transaction_metrics( + 'test_get_and_set:test_strict_redis_operation_enable_instance', + scoped_metrics=_enable_scoped_metrics, + rollup_metrics=_enable_rollup_metrics, + background_task=True) +@background_task() +def test_strict_redis_operation_enable_instance(loop): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + loop.run_until_complete(exercise_redis(client)) + +@override_application_settings(_disable_instance_settings) +@validate_transaction_metrics( + 'test_get_and_set:test_strict_redis_operation_disable_instance', + scoped_metrics=_disable_scoped_metrics, + rollup_metrics=_disable_rollup_metrics, + background_task=True) +@background_task() +def test_strict_redis_operation_disable_instance(loop): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=0) + loop.run_until_complete(exercise_redis(client)) diff --git a/tests/datastore_aredis/test_instance_info.py b/tests/datastore_aredis/test_instance_info.py new file mode 100644 index 0000000000..d97fd5a555 --- /dev/null +++ b/tests/datastore_aredis/test_instance_info.py @@ -0,0 +1,116 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +import aredis + +from newrelic.hooks.datastore_redis import _conn_attrs_to_dict, _instance_info + +REDIS_PY_VERSION = aredis.VERSION + +_instance_info_tests = [ + ((), {}, ("localhost", "6379", "0")), + ((), {"host": None}, ("localhost", "6379", "0")), + ((), {"host": ""}, ("localhost", "6379", "0")), + ((), {"db": None}, ("localhost", "6379", "0")), + ((), {"db": ""}, ("localhost", "6379", "0")), + ((), {"host": "127.0.0.1", "port": 1234, "db": 2}, ("127.0.0.1", "1234", "2")), + (("127.0.0.1", 1234, 2), {}, ("127.0.0.1", "1234", "2")), +] + + +class DisabledConnection(aredis.Connection): + @staticmethod + def connect(*args, **kwargs): + pass + + +class DisabledUnixConnection(aredis.UnixDomainSocketConnection, DisabledConnection): + pass + + +@pytest.mark.parametrize("args,kwargs,expected", _instance_info_tests) +def test_strict_redis_client_instance_info(args, kwargs, expected): + r = aredis.StrictRedis(*args, **kwargs) + conn_kwargs = r.connection_pool.connection_kwargs + assert _instance_info(conn_kwargs) == expected + +@pytest.mark.parametrize("args,kwargs,expected", _instance_info_tests) +def test_strict_redis_connection_instance_info(args, kwargs, expected): + r = aredis.StrictRedis(*args, **kwargs) + r.connection_pool.connection_class = DisabledConnection + connection = r.connection_pool.get_connection("SELECT") + try: + conn_kwargs = _conn_attrs_to_dict(connection) + assert _instance_info(conn_kwargs) == expected + finally: + r.connection_pool.release(connection) + + +_instance_info_from_url_tests = [ + (("redis://localhost:1234/",), {}, ("localhost", "1234", "0")), + (("redis://localhost:1234",), {}, ("localhost", "1234", "0")), + (("redis://user:password@localhost:6379",), {}, ("localhost", "6379", "0")), + (("redis://localhost:6379/2",), {}, ("localhost", "6379", "2")), + (("redis://localhost:6379",), {"db": 2}, ("localhost", "6379", "2")), + (("redis://@127.0.0.1:6379",), {}, ("127.0.0.1", "6379", "0")), + (("redis://:1234/",), {}, ("localhost", "1234", "0")), + (("redis://@:1234/",), {}, ("localhost", "1234", "0")), + (("redis://localhost:1234/garbage",), {}, ("localhost", "1234", "0")), +] + +# Behavior to default port to 6379 was added in v2.7.5 +# (https://github.com/redis/redis-py/commit/cfe1041bbb8a8887531810429879bffbe705b03a) +# and removed in v4.0.0b1 (https://github.com/redis/redis-py/blame/v4.0.0b1/redis/connection.py#L997) +if (3, 5, 3) >= REDIS_PY_VERSION >= (2, 7, 5): + _instance_info_from_url_tests.append((("redis://127.0.0.1",), {}, ("127.0.0.1", "6379", "0"))) + +if REDIS_PY_VERSION >= (2, 10): + _instance_info_from_url_tests.extend( + [ + (("rediss://localhost:6379/2/",), {}, ("localhost", "6379", "2")), # rediss: Not a typo + (("redis://localhost:6379",), {"host": "someotherhost"}, ("localhost", "6379", "0")), + (("redis://localhost:6379/2",), {"db": 3}, ("localhost", "6379", "2")), + (("redis://localhost:6379/2/?db=111",), {}, ("localhost", "6379", "111")), + (("redis://localhost:6379?db=2",), {}, ("localhost", "6379", "2")), + (("redis://localhost:6379/2?db=111",), {}, ("localhost", "6379", "111")), + (("unix:///path/to/socket.sock",), {}, ("localhost", "/path/to/socket.sock", "0")), + (("unix:///path/to/socket.sock?db=2",), {}, ("localhost", "/path/to/socket.sock", "2")), + (("unix:///path/to/socket.sock",), {"db": 2}, ("localhost", "/path/to/socket.sock", "2")), + ] + ) + + +@pytest.mark.parametrize("args,kwargs,expected", _instance_info_from_url_tests) +def test_strict_redis_client_from_url(args, kwargs, expected): + r = aredis.StrictRedis.from_url(*args, **kwargs) + conn_kwargs = r.connection_pool.connection_kwargs + assert _instance_info(conn_kwargs) == expected + + +@pytest.mark.parametrize("args,kwargs,expected", _instance_info_from_url_tests) +def test_strict_redis_connection_from_url(args, kwargs, expected): + r = aredis.StrictRedis.from_url(*args, **kwargs) + if r.connection_pool.connection_class is aredis.Connection: + r.connection_pool.connection_class = DisabledConnection + elif r.connection_pool.connection_class is aredis.UnixDomainSocketConnection: + r.connection_pool.connection_class = DisabledUnixConnection + else: + assert False, r.connection_pool.connection_class + connection = r.connection_pool.get_connection("SELECT") + try: + conn_kwargs = _conn_attrs_to_dict(connection) + assert _instance_info(conn_kwargs) == expected + finally: + r.connection_pool.release(connection) diff --git a/tests/datastore_aredis/test_multiple_dbs.py b/tests/datastore_aredis/test_multiple_dbs.py new file mode 100644 index 0000000000..f766784afe --- /dev/null +++ b/tests/datastore_aredis/test_multiple_dbs.py @@ -0,0 +1,120 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +import aredis + +from newrelic.api.background_task import background_task + +from testing_support.fixture.event_loop import event_loop as loop +from testing_support.fixtures import (validate_transaction_metrics, + override_application_settings) +from testing_support.db_settings import redis_settings +from testing_support.util import instance_hostname + +DB_MULTIPLE_SETTINGS = redis_settings() + +# Settings + +_enable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': True, +} +_disable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': False, +} + +# Metrics + +_base_scoped_metrics = ( + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/set', 1), + ('Datastore/operation/Redis/client_list', 1), +) + +_base_rollup_metrics = ( + ('Datastore/all', 3), + ('Datastore/allOther', 3), + ('Datastore/Redis/all', 3), + ('Datastore/Redis/allOther', 3), + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/get', 1), + ('Datastore/operation/Redis/client_list', 1), +) + +_disable_scoped_metrics = list(_base_scoped_metrics) +_disable_rollup_metrics = list(_base_rollup_metrics) + +_enable_scoped_metrics = list(_base_scoped_metrics) +_enable_rollup_metrics = list(_base_rollup_metrics) + +if len(DB_MULTIPLE_SETTINGS) > 1: + redis_1 = DB_MULTIPLE_SETTINGS[0] + redis_2 = DB_MULTIPLE_SETTINGS[1] + + host_1 = instance_hostname(redis_1['host']) + port_1 = redis_1['port'] + + host_2 = instance_hostname(redis_2['host']) + port_2 = redis_2['port'] + + instance_metric_name_1 = 'Datastore/instance/Redis/%s/%s' % (host_1, port_1) + instance_metric_name_2 = 'Datastore/instance/Redis/%s/%s' % (host_2, port_2) + + _enable_rollup_metrics.extend([ + (instance_metric_name_1, 2), + (instance_metric_name_2, 1), + ]) + + _disable_rollup_metrics.extend([ + (instance_metric_name_1, None), + (instance_metric_name_2, None), + ]) + +async def exercise_redis(client_1, client_2): + await client_1.set('key', 'value') + await client_1.get('key') + + await client_2.execute_command('CLIENT', 'LIST', parse='LIST') + +@pytest.mark.skipif(len(DB_MULTIPLE_SETTINGS) < 2, + reason='Test environment not configured with multiple databases.') +@override_application_settings(_enable_instance_settings) +@validate_transaction_metrics('test_multiple_dbs:test_multiple_datastores_enabled', + scoped_metrics=_enable_scoped_metrics, + rollup_metrics=_enable_rollup_metrics, + background_task=True) +@background_task() +def test_multiple_datastores_enabled(loop): + redis1 = DB_MULTIPLE_SETTINGS[0] + redis2 = DB_MULTIPLE_SETTINGS[1] + + client_1 = aredis.StrictRedis(host=redis1['host'], port=redis1['port'], db=0) + client_2 = aredis.StrictRedis(host=redis2['host'], port=redis2['port'], db=1) + loop.run_until_complete(exercise_redis(client_1, client_2)) + +@pytest.mark.skipif(len(DB_MULTIPLE_SETTINGS) < 2, + reason='Test environment not configured with multiple databases.') +@override_application_settings(_disable_instance_settings) +@validate_transaction_metrics('test_multiple_dbs:test_multiple_datastores_disabled', + scoped_metrics=_disable_scoped_metrics, + rollup_metrics=_disable_rollup_metrics, + background_task=True) +@background_task() +def test_multiple_datastores_disabled(loop): + redis1 = DB_MULTIPLE_SETTINGS[0] + redis2 = DB_MULTIPLE_SETTINGS[1] + + client_1 = aredis.StrictRedis(host=redis1['host'], port=redis1['port'], db=0) + client_2 = aredis.StrictRedis(host=redis2['host'], port=redis2['port'], db=1) + loop.run_until_complete(exercise_redis(client_1, client_2)) diff --git a/tests/datastore_aredis/test_span_event.py b/tests/datastore_aredis/test_span_event.py new file mode 100644 index 0000000000..2bd238bdae --- /dev/null +++ b/tests/datastore_aredis/test_span_event.py @@ -0,0 +1,137 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +import aredis + +from newrelic.api.transaction import current_transaction +from newrelic.api.background_task import background_task + +from testing_support.db_settings import redis_settings +from testing_support.fixture.event_loop import event_loop as loop +from testing_support.fixtures import override_application_settings +from testing_support.validators.validate_span_events import ( + validate_span_events) +from testing_support.util import instance_hostname + + +DB_SETTINGS = redis_settings()[0] +DATABASE_NUMBER = 0 + + +# Settings + +_enable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': True, + 'datastore_tracer.database_name_reporting.enabled': True, + 'distributed_tracing.enabled': True, + 'span_events.enabled': True, +} +_disable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': False, + 'datastore_tracer.database_name_reporting.enabled': False, + 'distributed_tracing.enabled': True, + 'span_events.enabled': True, +} + + +async def _exercise_db(): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=DATABASE_NUMBER) + + await client.set('key', 'value') + await client.get('key') + + await client.execute_command('CLIENT', 'LIST', parse='LIST') + + +# Tests + +@pytest.mark.parametrize('db_instance_enabled', (True, False)) +@pytest.mark.parametrize('instance_enabled', (True, False)) +def test_span_events(instance_enabled, db_instance_enabled, loop): + guid = 'dbb533c53b749e0b' + priority = 0.5 + + common = { + 'type': 'Span', + 'transactionId': guid, + 'priority': priority, + 'sampled': True, + 'category': 'datastore', + 'component': 'Redis', + 'span.kind': 'client', + } + exact_agents = {} + + if instance_enabled: + settings = _enable_instance_settings.copy() + hostname = instance_hostname(DB_SETTINGS['host']) + exact_agents.update({ + 'peer.address': '%s:%s' % (hostname, DB_SETTINGS['port']), + 'peer.hostname': hostname, + }) + else: + settings = _disable_instance_settings.copy() + exact_agents.update({ + 'peer.address': 'Unknown:Unknown', + 'peer.hostname': 'Unknown', + }) + + if db_instance_enabled and instance_enabled: + exact_agents.update({ + 'db.instance': str(DATABASE_NUMBER), + }) + unexpected_agents = () + else: + settings['attributes.exclude'] = ['db.instance'] + unexpected_agents = ('db.instance',) + + query_1 = common.copy() + query_1['name'] = 'Datastore/operation/Redis/set' + + query_2 = common.copy() + query_2['name'] = 'Datastore/operation/Redis/get' + + query_3 = common.copy() + query_3['name'] = 'Datastore/operation/Redis/client_list' + + @validate_span_events( + count=1, + exact_intrinsics=query_1, + unexpected_intrinsics=('db.instance'), + exact_agents=exact_agents, + unexpected_agents=unexpected_agents) + @validate_span_events( + count=1, + exact_intrinsics=query_2, + unexpected_intrinsics=('db.instance'), + exact_agents=exact_agents, + unexpected_agents=unexpected_agents) + @validate_span_events( + count=1, + exact_intrinsics=query_3, + unexpected_intrinsics=('db.instance'), + exact_agents=exact_agents, + unexpected_agents=unexpected_agents) + @override_application_settings(settings) + @background_task(name='span_events') + def _test(): + txn = current_transaction() + txn.guid = guid + txn._priority = priority + txn._sampled = True + loop.run_until_complete(_exercise_db()) + + _test() diff --git a/tests/datastore_aredis/test_trace_node.py b/tests/datastore_aredis/test_trace_node.py new file mode 100644 index 0000000000..9741bfbd60 --- /dev/null +++ b/tests/datastore_aredis/test_trace_node.py @@ -0,0 +1,127 @@ +# Copyright 2010 New Relic, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import aredis + +from testing_support.fixture.event_loop import event_loop as loop +from testing_support.fixtures import (validate_tt_collector_json, + override_application_settings) +from testing_support.util import instance_hostname +from testing_support.db_settings import redis_settings + +from newrelic.api.background_task import background_task + +DB_SETTINGS = redis_settings()[0] +DATABASE_NUMBER = 0 + +# Settings + +_enable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': True, + 'datastore_tracer.database_name_reporting.enabled': True, +} +_disable_instance_settings = { + 'datastore_tracer.instance_reporting.enabled': False, + 'datastore_tracer.database_name_reporting.enabled': False, +} +_instance_only_settings = { + 'datastore_tracer.instance_reporting.enabled': True, + 'datastore_tracer.database_name_reporting.enabled': False, +} +_database_only_settings = { + 'datastore_tracer.instance_reporting.enabled': False, + 'datastore_tracer.database_name_reporting.enabled': True, +} + +# Expected parameters + +_enabled_required = { + 'host': instance_hostname(DB_SETTINGS['host']), + 'port_path_or_id': str(DB_SETTINGS['port']), + 'db.instance': str(DATABASE_NUMBER), +} +_enabled_forgone = {} + +_disabled_required = {} +_disabled_forgone = { + 'host': 'VALUE NOT USED', + 'port_path_or_id': 'VALUE NOT USED', + 'db.instance': 'VALUE NOT USED', +} + +_instance_only_required = { + 'host': instance_hostname(DB_SETTINGS['host']), + 'port_path_or_id': str(DB_SETTINGS['port']), +} +_instance_only_forgone = { + 'db.instance': str(DATABASE_NUMBER), +} + +_database_only_required = { + 'db.instance': str(DATABASE_NUMBER), +} +_database_only_forgone = { + 'host': 'VALUE NOT USED', + 'port_path_or_id': 'VALUE NOT USED', +} + + +# Query + +async def _exercise_db(): + client = aredis.StrictRedis(host=DB_SETTINGS['host'], + port=DB_SETTINGS['port'], db=DATABASE_NUMBER) + + await client.set('key', 'value') + await client.get('key') + + await client.execute_command('CLIENT', 'LIST', parse='LIST') + + +# Tests + +@override_application_settings(_enable_instance_settings) +@validate_tt_collector_json( + datastore_params=_enabled_required, + datastore_forgone_params=_enabled_forgone) +@background_task() +def test_trace_node_datastore_params_enable_instance(loop): + loop.run_until_complete(_exercise_db()) + + +@override_application_settings(_disable_instance_settings) +@validate_tt_collector_json( + datastore_params=_disabled_required, + datastore_forgone_params=_disabled_forgone) +@background_task() +def test_trace_node_datastore_params_disable_instance(loop): + loop.run_until_complete(_exercise_db()) + + +@override_application_settings(_instance_only_settings) +@validate_tt_collector_json( + datastore_params=_instance_only_required, + datastore_forgone_params=_instance_only_forgone) +@background_task() +def test_trace_node_datastore_params_instance_only(loop): + loop.run_until_complete(_exercise_db()) + + +@override_application_settings(_database_only_settings) +@validate_tt_collector_json( + datastore_params=_database_only_required, + datastore_forgone_params=_database_only_forgone) +@background_task() +def test_trace_node_datastore_params_database_only(loop): + loop.run_until_complete(_exercise_db())