def test_environment_analytics_overrides(self):
        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='False', OTEL_TRACE_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.analytics_enabled)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='False', OTEL_TRACE_ANALYTICS_ENABLED='False')):
            config = Config()
            self.assertFalse(config.analytics_enabled)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True', OTEL_TRACE_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.analytics_enabled)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True', OTEL_TRACE_ANALYTICS_ENABLED='False')):
            config = Config()
            self.assertFalse(config.analytics_enabled)
    def test_get_analytics_sample_rate(self):
        """" Check method for accessing sample rate based on configuration """
        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=True, analytics_sample_rate=0.5)
        self.assertEqual(ic.get_analytics_sample_rate(), 0.5)

        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=True)
        self.assertEqual(ic.get_analytics_sample_rate(), 1.0)

        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=False)
        self.assertIsNone(ic.get_analytics_sample_rate())

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True')):
            config = Config()
            ic = IntegrationConfig(config, 'foo')
            self.assertEqual(ic.get_analytics_sample_rate(use_global_config=True), 1.0)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='False')):
            config = Config()
            ic = IntegrationConfig(config, 'foo')
            self.assertIsNone(ic.get_analytics_sample_rate(use_global_config=True))
    def test_environment_analytics_enabled(self):
        # default
        self.assertFalse(self.config.analytics_enabled)
        self.assertIsNone(self.config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.analytics_enabled)
            self.assertIsNone(config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.foo.analytics_enabled)
            self.assertEqual(config.foo.analytics_sample_rate, 1.0)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='False')):
            config = Config()
            self.assertFalse(config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='True', OTEL_FOO_ANALYTICS_SAMPLE_RATE='0.5')):
            config = Config()
            self.assertTrue(config.foo.analytics_enabled)
            self.assertEqual(config.foo.analytics_sample_rate, 0.5)
 def setUp(self):
     self.config = Config()
     self.integration_config = IntegrationConfig(self.config, 'test')
class TestIntegrationConfig(BaseTestCase):
    def setUp(self):
        self.config = Config()
        self.integration_config = IntegrationConfig(self.config, 'test')

    def test_is_a_dict(self):
        assert isinstance(self.integration_config, dict)

    def test_allow_item_access(self):
        self.integration_config['setting'] = 'value'

        # Can be accessed both as item and attr accessor
        assert self.integration_config.setting == 'value'
        assert self.integration_config['setting'] == 'value'

    def test_allow_attr_access(self):
        self.integration_config.setting = 'value'

        # Can be accessed both as item and attr accessor
        assert self.integration_config.setting == 'value'
        assert self.integration_config['setting'] == 'value'

    def test_allow_both_access(self):
        self.integration_config.setting = 'value'
        assert self.integration_config['setting'] == 'value'
        assert self.integration_config.setting == 'value'

        self.integration_config['setting'] = 'new-value'
        assert self.integration_config.setting == 'new-value'
        assert self.integration_config['setting'] == 'new-value'

    def test_allow_configuring_http(self):
        self.integration_config.http.trace_headers('integration_header')
        assert self.integration_config.http.header_is_traced('integration_header')
        assert not self.integration_config.http.header_is_traced('other_header')

    def test_allow_exist_both_global_and_integration_config(self):
        self.config.trace_headers('global_header')
        assert self.integration_config.header_is_traced('global_header')

        self.integration_config.http.trace_headers('integration_header')
        assert self.integration_config.header_is_traced('integration_header')
        assert not self.integration_config.header_is_traced('global_header')
        assert not self.config.header_is_traced('integration_header')

    def test_environment_analytics_enabled(self):
        # default
        self.assertFalse(self.config.analytics_enabled)
        self.assertIsNone(self.config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.analytics_enabled)
            self.assertIsNone(config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='True')):
            config = Config()
            self.assertTrue(config.foo.analytics_enabled)
            self.assertEqual(config.foo.analytics_sample_rate, 1.0)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='False')):
            config = Config()
            self.assertFalse(config.foo.analytics_enabled)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='True', OTEL_FOO_ANALYTICS_SAMPLE_RATE='0.5')):
            config = Config()
            self.assertTrue(config.foo.analytics_enabled)
            self.assertEqual(config.foo.analytics_sample_rate, 0.5)

    def test_analytics_enabled_attribute(self):
        """" Confirm environment variable and kwargs are handled properly """
        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=True)
        self.assertTrue(ic.analytics_enabled)

        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=False)
        self.assertFalse(ic.analytics_enabled)

        with self.override_env(dict(OTEL_FOO_ANALYTICS_ENABLED='True')):
            ic = IntegrationConfig(self.config, 'foo', analytics_enabled=False)
            self.assertFalse(ic.analytics_enabled)

    def test_get_analytics_sample_rate(self):
        """" Check method for accessing sample rate based on configuration """
        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=True, analytics_sample_rate=0.5)
        self.assertEqual(ic.get_analytics_sample_rate(), 0.5)

        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=True)
        self.assertEqual(ic.get_analytics_sample_rate(), 1.0)

        ic = IntegrationConfig(self.config, 'foo', analytics_enabled=False)
        self.assertIsNone(ic.get_analytics_sample_rate())

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='True')):
            config = Config()
            ic = IntegrationConfig(config, 'foo')
            self.assertEqual(ic.get_analytics_sample_rate(use_global_config=True), 1.0)

        with self.override_env(dict(OTEL_ANALYTICS_ENABLED='False')):
            config = Config()
            ic = IntegrationConfig(config, 'foo')
            self.assertIsNone(ic.get_analytics_sample_rate(use_global_config=True))
 def config(self):
     yield Config()
예제 #7
0
 def setUp(self):
     self.config = Config()
     self.tracer = get_dummy_tracer()
예제 #8
0
class GlobalConfigTestCase(TestCase):
    """Test the `Configuration` class that stores integration settings"""
    def setUp(self):
        self.config = Config()
        self.tracer = get_dummy_tracer()

    def test_registration(self):
        # ensure an integration can register a new list of settings
        settings = {
            'distributed_tracing': True,
        }
        self.config._add('requests', settings)
        assert self.config.requests['distributed_tracing'] is True

    def test_settings_copy(self):
        # ensure that once an integration is registered, a copy
        # of the settings is stored to avoid side-effects
        experimental = {
            'request_enqueuing': True,
        }
        settings = {
            'distributed_tracing': True,
            'experimental': experimental,
        }
        self.config._add('requests', settings)

        settings['distributed_tracing'] = False
        experimental['request_enqueuing'] = False
        assert self.config.requests['distributed_tracing'] is True
        assert self.config.requests['experimental']['request_enqueuing'] is True

    def test_missing_integration_key(self):
        # ensure a meaningful exception is raised when an integration
        # that is not available is retrieved in the configuration
        # object
        with pytest.raises(KeyError) as e:
            self.config.new_integration['some_key']

        assert isinstance(e.value, KeyError)

    def test_global_configuration(self):
        # ensure a global configuration is available in the `oteltrace` module
        assert isinstance(global_config, Config)

    def test_settings_merge(self):
        """
        When calling `config._add()`
            when existing settings exist
                we do not overwrite the existing settings
        """
        self.config.requests['split_by_domain'] = True
        self.config._add('requests', dict(split_by_domain=False))
        assert self.config.requests['split_by_domain'] is True

    def test_settings_overwrite(self):
        """
        When calling `config._add(..., merge=False)`
            when existing settings exist
                we overwrite the existing settings
        """
        self.config.requests['split_by_domain'] = True
        self.config._add('requests', dict(split_by_domain=False), merge=False)
        assert self.config.requests['split_by_domain'] is False

    def test_settings_merge_deep(self):
        """
        When calling `config._add()`
            when existing "deep" settings exist
                we do not overwrite the existing settings
        """
        self.config.requests['a'] = dict(
            b=dict(
                c=True,
            ),
        )
        self.config._add('requests', dict(
            a=dict(
                b=dict(
                    c=False,
                    d=True,
                ),
            ),
        ))
        assert self.config.requests['a']['b']['c'] is True
        assert self.config.requests['a']['b']['d'] is True

    def test_settings_hook(self):
        """
        When calling `Hooks._emit()`
            When there is a hook registered
                we call the hook as expected
        """
        # Setup our hook
        @self.config.web.hooks.on('request')
        def on_web_request(span):
            span.set_tag('web.request', '/')

        # Create our span
        span = self.tracer.start_span('web.request')
        assert 'web.request' not in span.meta

        # Emit the span
        self.config.web.hooks._emit('request', span)

        # Assert we updated the span as expected
        assert span.get_tag('web.request') == '/'

    def test_settings_hook_args(self):
        """
        When calling `Hooks._emit()` with arguments
            When there is a hook registered
                we call the hook as expected
        """
        # Setup our hook
        @self.config.web.hooks.on('request')
        def on_web_request(span, request, response):
            span.set_tag('web.request', request)
            span.set_tag('web.response', response)

        # Create our span
        span = self.tracer.start_span('web.request')
        assert 'web.request' not in span.meta

        # Emit the span
        # DEV: The actual values don't matter, we just want to test args + kwargs usage
        self.config.web.hooks._emit('request', span, 'request', response='response')

        # Assert we updated the span as expected
        assert span.get_tag('web.request') == 'request'
        assert span.get_tag('web.response') == 'response'

    def test_settings_hook_args_failure(self):
        """
        When calling `Hooks._emit()` with arguments
            When there is a hook registered that is missing parameters
                we do not raise an exception
        """
        # Setup our hook
        # DEV: We are missing the required "response" argument
        @self.config.web.hooks.on('request')
        def on_web_request(span, request):
            span.set_tag('web.request', request)

        # Create our span
        span = self.tracer.start_span('web.request')
        assert 'web.request' not in span.meta

        # Emit the span
        # DEV: This also asserts that no exception was raised
        self.config.web.hooks._emit('request', span, 'request', response='response')

        # Assert we did not update the span
        assert 'web.request' not in span.meta

    def test_settings_multiple_hooks(self):
        """
        When calling `Hooks._emit()`
            When there are multiple hooks registered
                we do not raise an exception
        """
        # Setup our hooks
        @self.config.web.hooks.on('request')
        def on_web_request(span):
            span.set_tag('web.request', '/')

        @self.config.web.hooks.on('request')
        def on_web_request2(span):
            span.set_tag('web.status', 200)

        @self.config.web.hooks.on('request')
        def on_web_request3(span):
            span.set_tag('web.method', 'GET')

        # Create our span
        span = self.tracer.start_span('web.request')
        assert 'web.request' not in span.meta
        assert 'web.status' not in span.meta
        assert 'web.method' not in span.meta

        # Emit the span
        self.config.web.hooks._emit('request', span)

        # Assert we updated the span as expected
        assert span.get_tag('web.request') == '/'
        assert span.get_tag('web.status') == '200'
        assert span.get_tag('web.method') == 'GET'

    def test_settings_hook_failure(self):
        """
        When calling `Hooks._emit()`
            When the hook raises an exception
                we do not raise an exception
        """
        # Setup our failing hook
        on_web_request = mock.Mock(side_effect=Exception)
        self.config.web.hooks.register('request')(on_web_request)

        # Create our span
        span = self.tracer.start_span('web.request')

        # Emit the span
        # DEV: This is the test, to ensure no exceptions are raised
        self.config.web.hooks._emit('request', span)
        on_web_request.assert_called()

    def test_settings_no_hook(self):
        """
        When calling `Hooks._emit()`
            When no hook is registered
                we do not raise an exception
        """
        # Create our span
        span = self.tracer.start_span('web.request')

        # Emit the span
        # DEV: This is the test, to ensure no exceptions are raised
        self.config.web.hooks._emit('request', span)

    def test_settings_no_span(self):
        """
        When calling `Hooks._emit()`
            When no span is provided
                we do not raise an exception
        """
        # Setup our hooks
        @self.config.web.hooks.on('request')
        def on_web_request(span):
            span.set_tag('web.request', '/')

        # Emit the span
        # DEV: This is the test, to ensure no exceptions are raised
        self.config.web.hooks._emit('request', None)