예제 #1
0
def test_enable_bad_rules(rule, exc, tracer):
    with override_env(dict(DD_APPSEC_RULES=rule)):
        with pytest.raises(exc):
            _enable_appsec(tracer)

    # by default enable must not crash but display errors in the logs
    with override_global_config(dict(_raise=False)):
        with override_env(dict(DD_APPSEC_RULES=rule)):
            _enable_appsec(tracer)
예제 #2
0
def test_additional_headers():
    with override_env(
            dict(_DD_TRACE_WRITER_ADDITIONAL_HEADERS=
                 "additional-header:additional-value,header2:value2")):
        writer = AgentWriter(agent_url="http://localhost:9126")
        assert writer._headers["additional-header"] == "additional-value"
        assert writer._headers["header2"] == "value2"
예제 #3
0
    def test_tracer_metrics(self):
        # Mock socket.socket to hijack the dogstatsd socket
        with mock.patch("socket.socket"):
            # configure tracer for runtime metrics
            interval = 1.0 / 4
            with override_env(dict(DD_RUNTIME_METRICS_INTERVAL=str(interval))):
                self.tracer.configure(collect_metrics=True)
                self.tracer.set_tags({"env": "tests.dog"})

                with self.override_global_tracer(self.tracer):
                    # spans are started for three services but only web and worker
                    # span types should be included in tags for runtime metrics
                    root = self.start_span("parent",
                                           service="parent",
                                           span_type=SpanTypes.WEB)
                    context = root.context
                    child = self.start_span("child",
                                            service="child",
                                            span_type=SpanTypes.WORKER,
                                            child_of=context)
                    self.start_span("query",
                                    service="db",
                                    span_type=SpanTypes.SQL,
                                    child_of=child.context)
                    time.sleep(interval * 4)
                    # Get the mocked socket for inspection later
                    statsd_socket = self.tracer._runtime_worker._dogstatsd_client.socket
                    # now stop collection
                    self.tracer.configure(collect_metrics=False)

                received = [
                    s.args[0].decode("utf-8")
                    for s in statsd_socket.send.mock_calls
                ]

        # we expect more than one flush since it is also called on shutdown
        assert len(received) > 1

        # expect all metrics in default set are received
        # DEV: dogstatsd gauges in form "{metric_name}:{metric_value}|g#t{tag_name}:{tag_value},..."
        assert (DEFAULT_RUNTIME_METRICS & set([
            gauge.split(":")[0] for packet in received
            for gauge in packet.split("\n")
        ]) == DEFAULT_RUNTIME_METRICS)

        # check to last set of metrics returned to confirm tags were set
        for gauge in received[-1:]:
            self.assertRegexpMatches(gauge, "service:parent")
            self.assertRegexpMatches(gauge, "service:child")
            self.assertNotRegexpMatches(gauge, "service:db")
            self.assertRegexpMatches(gauge, "env:tests.dog")
            self.assertRegexpMatches(gauge, "lang_interpreter:CPython")
            self.assertRegexpMatches(gauge, "lang_version:")
            self.assertRegexpMatches(gauge, "lang:python")
            self.assertRegexpMatches(gauge, "tracer_version:")
예제 #4
0
def test_environment_header_tags():
    with override_env(
            dict(
                DD_TRACE_HEADER_TAGS="Host:http.host,User-agent:http.user_agent"
            )):
        config = Config()

    assert config.http.is_header_tracing_configured
    assert config._header_tag_name("Host") == "http.host"
    assert config._header_tag_name("User-agent") == "http.user_agent"
    # Case insensitive
    assert config._header_tag_name("User-Agent") == "http.user_agent"
예제 #5
0
def test_datadog_sampler_init():
    # No args
    sampler = DatadogSampler()
    assert sampler.rules == []
    assert isinstance(sampler.limiter, RateLimiter)
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With rules
    rule = SamplingRule(sample_rate=1)
    sampler = DatadogSampler(rules=[rule])
    assert sampler.rules == [rule]
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With rate limit
    sampler = DatadogSampler(rate_limit=10)
    assert sampler.limiter.rate_limit == 10
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With default_sample_rate
    sampler = DatadogSampler(default_sample_rate=0.5)
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, SamplingRule)
    assert sampler.default_sampler.sample_rate == 0.5

    # From env variables
    with override_env(
            dict(DD_TRACE_SAMPLE_RATE='0.5', DD_TRACE_RATE_LIMIT='10')):
        sampler = DatadogSampler()
        assert sampler.limiter.rate_limit == 10
        assert isinstance(sampler.default_sampler, SamplingRule)
        assert sampler.default_sampler.sample_rate == 0.5

    # Invalid rules
    for val in (None, True, False, object(), 1, Exception()):
        with pytest.raises(TypeError):
            DatadogSampler(rules=[val])

    # Ensure rule order
    rule_1 = SamplingRule(sample_rate=1)
    rule_2 = SamplingRule(sample_rate=0.5, service='test')
    rule_3 = SamplingRule(sample_rate=0.25, name='flask.request')
    sampler = DatadogSampler(rules=[rule_1, rule_2, rule_3])
    assert sampler.rules == [rule_1, rule_2, rule_3]
예제 #6
0
def test_enable_custom_rules():
    with override_env(dict(DD_APPSEC_RULES=RULES_GOOD_PATH)):
        processor = AppSecSpanProcessor()

    assert processor.enabled
    assert processor.rules == RULES_GOOD_PATH