Skip to content

Commit d46fc4a

Browse files
committed
feat: add process discovery tests
1 parent 28b2d98 commit d46fc4a

File tree

12 files changed

+243
-20
lines changed

12 files changed

+243
-20
lines changed

manifests/dotnet.yml

+1
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ tests/:
449449
Test_Parametric_OtelSpan_Set_Name: bug (APMAPI-778) # updates the operation name of the span not the resource name
450450
Test_Parametric_Otel_Baggage: incomplete_test_app (otel baggage endpoints are not implemented)
451451
Test_Parametric_Otel_Current_Span: incomplete_test_app (otel current span endpoint are not implemented)
452+
test_process_directory.py: missing_feature
452453
test_span_events.py: missing_feature
453454
test_span_links.py: missing_feature
454455
test_telemetry.py:

manifests/golang.yml

+1
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ tests/:
568568
Test_Otel_Env_Vars: v1.66.0
569569
test_otel_span_with_baggage.py:
570570
Test_Otel_Span_With_Baggage: missing_feature
571+
test_process_directory.py: missing_feature
571572
test_parametric_endpoints.py:
572573
Test_Parametric_DDSpan_Add_Link: missing_feature (add_link endpoint is not implemented)
573574
Test_Parametric_DDSpan_Set_Resource: missing_feature (does not support setting a resource name after span creation)

manifests/java.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,7 @@ tests/:
16091609
'*': incomplete_test_app (endpoint not implemented)
16101610
spring-boot: v1.39.0
16111611
parametric/:
1612+
test_process_directory.py: missing_feature
16121613
test_config_consistency.py:
16131614
Test_Config_Dogstatsd: missing_feature (default hostname is inconsistent)
16141615
Test_Config_RateLimit: v1.41.1

manifests/nodejs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ tests/:
799799
express4: *ref_5_26_0
800800
express5: *ref_5_26_0
801801
parametric/:
802+
test_process_directory.py: missing_feature
802803
test_128_bit_traceids.py:
803804
Test_128_Bit_Traceids: *ref_3_0_0
804805
test_config_consistency.py:

manifests/php.yml

+1
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ tests/:
386386
test_context_propagation.py:
387387
Test_Otel_Context_Propagation_Default_Propagator_Api: incomplete_test_app (endpoint not implemented)
388388
parametric/:
389+
test_process_directory.py: missing_feature
389390
test_128_bit_traceids.py:
390391
Test_128_Bit_Traceids: v0.84.0
391392
test_config_consistency.py:

manifests/python.yml

+1
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@ tests/:
771771
'*': incomplete_test_app (endpoint not implemented)
772772
flask-poc: v2.19.0
773773
parametric/:
774+
test_process_directory.py: missing_feature
774775
test_128_bit_traceids.py:
775776
Test_128_Bit_Traceids: v2.6.0
776777
test_config_consistency.py:

manifests/ruby.yml

+1
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ tests/:
411411
'*': incomplete_test_app (endpoint not implemented)
412412
rails70: v2.0.0
413413
parametric/:
414+
test_process_directory.py: missing_feature
414415
test_config_consistency.py:
415416
Test_Config_Dogstatsd: missing_feature
416417
Test_Config_RateLimit: v2.0.0
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""
2+
Test the instrumented process discovery mechanism feature.
3+
"""
4+
5+
import pytest
6+
import json
7+
import msgpack
8+
from jsonschema import validate as validation_jsonschema
9+
from utils import features, scenarios
10+
11+
12+
def find_dd_memfds(test_library, pid: int) -> list[str]:
13+
_, out = test_library.container_exec_run(f"find /proc/{pid}/fd -lname '/memfd:datadog-tracer-info*'")
14+
if not out:
15+
return []
16+
17+
memfds = out.split()
18+
return memfds
19+
20+
21+
def validate_schema(input: str) -> bool:
22+
schema = None
23+
with open("utils/interfaces/schemas/library/process-discovery.json", "r") as f:
24+
schema = json.load(f)
25+
26+
try:
27+
validation_jsonschema(input, schema)
28+
return True
29+
except Exception:
30+
return False
31+
32+
33+
def read_memfd(test_library, memfd_path: str):
34+
rc, output = test_library.container_exec_run_raw(f"cat {memfd_path}")
35+
if rc != 0:
36+
return rc, output
37+
38+
return rc, msgpack.unpackb(output)
39+
40+
41+
@scenarios.parametric
42+
@features.process_discovery
43+
class Test_ProcessDiscovery:
44+
@pytest.mark.parametrize(
45+
"library_env",
46+
[
47+
{"DD_SERVICE": "a", "DD_ENV": "test", "DD_VERSION": "0.1.0"},
48+
{"DD_SERVICE": "b", "DD_ENV": "second-test", "DD_VERSION": "0.2.0"},
49+
],
50+
)
51+
def test_metadata_content(self, test_library, library_env):
52+
"""
53+
Verify the content of the memfd file matches the expected metadata format and structure
54+
"""
55+
with test_library:
56+
# NOTE(@dmehala): the server is started on container is always pid 1.
57+
# That's a strong assumption :hehe:
58+
# Maybe we should use `pidof pidof parametric-http-server` instead.
59+
memfds = find_dd_memfds(test_library, 1)
60+
assert len(memfds) == 1
61+
62+
rc, tracer_metadata = read_memfd(test_library, memfds[0])
63+
assert rc == 0
64+
assert validate_schema(tracer_metadata) == True
65+
66+
assert tracer_metadata["schema_version"] == 1
67+
assert tracer_metadata["runtime_id"]
68+
# assert tracer_metadata["hostname"]
69+
# TODO(@dmehala): how to get the version?
70+
# assert tracer_metadata["tracer_version"] ==
71+
assert tracer_metadata["tracer_language"] == test_library.lang
72+
assert tracer_metadata["service_name"] == library_env["DD_SERVICE"]
73+
assert tracer_metadata["service_version"] == library_env["DD_VERSION"]
74+
assert tracer_metadata["service_env"] == library_env["DD_ENV"]

utils/_features.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,9 @@ def semantic_core_validations(test_object):
17241724
return test_object
17251725

17261726
@staticmethod
1727-
def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(test_object):
1727+
def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(
1728+
test_object,
1729+
):
17281730
"""[AWS-SQS][Span Creation][Context Propagation][AWS X-Ray] with dd-trace
17291731
17301732
https://feature-parity.us1.prod.dog/#/?feature=263
@@ -1733,7 +1735,9 @@ def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(test_
17331735
return test_object
17341736

17351737
@staticmethod
1736-
def aws_sqs_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
1738+
def aws_sqs_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
1739+
test_object,
1740+
):
17371741
"""[AWS-SQS][Span Creation][Context Propagation][AWS Message Attributes] with dd-trace
17381742
17391743
https://feature-parity.us1.prod.dog/#/?feature=264
@@ -1796,7 +1800,9 @@ def rabbitmq_span_creationcontext_propagation_with_dd_trace(test_object):
17961800
return test_object
17971801

17981802
@staticmethod
1799-
def aws_sns_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
1803+
def aws_sns_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
1804+
test_object,
1805+
):
18001806
"""[AWS-SNS][Span Creation][Context Propagation] with dd-trace
18011807
18021808
https://feature-parity.us1.prod.dog/#/?feature=271
@@ -1850,7 +1856,9 @@ def host_block_list(test_object):
18501856
return test_object
18511857

18521858
@staticmethod
1853-
def aws_kinesis_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
1859+
def aws_kinesis_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
1860+
test_object,
1861+
):
18541862
"""[AWS-Kinesis][Span Creation][Context Propagation] with dd-trace
18551863
18561864
https://feature-parity.us1.prod.dog/#/?feature=280
@@ -2390,5 +2398,15 @@ def otel_propagators_api(test_object):
23902398
pytest.mark.features(feature_id=361)(test_object)
23912399
return test_object
23922400

2401+
@staticmethod
2402+
def process_discovery(test_object):
2403+
"""Process Disocvery
2404+
2405+
https://feature-parity.us1.prod.dog/#/?feature=362
2406+
RFC: <https://docs.google.com/document/d/1kcW6BLdYxXeTSUz31cBqoqfW1Jjs0IDljfKeUfIRQp4/edit?tab=t.0>
2407+
"""
2408+
pytest.mark.features(feature_id=362)(test_object)
2409+
return test_object
2410+
23932411

23942412
features = _Features()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "/library/process-discovery.json",
4+
"title": "Tracer Metadata",
5+
"description": "Metadata format used for process discovery",
6+
"type": "object",
7+
"properties": {
8+
"schema_version": {
9+
"type": "integer",
10+
"description": "Version of the schema"
11+
},
12+
"runtime_id": {
13+
"type": "string",
14+
"description": "Runtime UUID"
15+
},
16+
"tracer_version": {
17+
"type": "string",
18+
"description": "Version of the Datadog tracer library"
19+
},
20+
"tracer_language": {
21+
"type": "string",
22+
"description": "Programming language of the tracer library"
23+
},
24+
"hostname": {
25+
"type": "string",
26+
"description": "An identifier for the machine running the process"
27+
},
28+
"service_name": {
29+
"type": "string",
30+
"description": "Name of the service being instrumented"
31+
},
32+
"service_env": {
33+
"type": "string",
34+
"description": "Environment of the service being instrumented"
35+
},
36+
"service_version": {
37+
"type": "string",
38+
"description": "Version of the service being instrumented"
39+
}
40+
},
41+
"required": [
42+
"schema_version",
43+
"tracer_version",
44+
"tracer_language",
45+
"hostname"
46+
]
47+
}
48+
49+

0 commit comments

Comments
 (0)