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)
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"
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:")
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"
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]
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