Skip to content

Commit

Permalink
add span links system tests for nodejs (#2065)
Browse files Browse the repository at this point in the history
* add span links system tests for nodejs

---------

Co-authored-by: Munir Abdinur <[email protected]>
  • Loading branch information
khanayan123 and mabdinur authored May 22, 2024
1 parent e0fc29b commit cfbe667
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
3 changes: 2 additions & 1 deletion manifests/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ tests/:
TestDynamicConfigV2: v4.23.0
test_otel_api_interoperability.py: missing_feature
test_otel_sdk_interoperability.py: missing_feature
test_span_links.py: missing_feature
test_span_links.py:
Test_Span_Links: v5.3.0
test_telemetry.py:
Test_Defaults: v5.6.0
Test_Environment: v5.6.0
Expand Down
8 changes: 4 additions & 4 deletions tests/parametric/test_otel_span_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def test_otel_set_attributes_separately(self, test_agent, test_library):
@missing_feature(context.library == "dotnet", reason="Not implemented")
@missing_feature(context.library < "[email protected]", reason="Implemented in 1.26.0")
@missing_feature(context.library == "golang", reason="Not implemented")
@missing_feature(context.library == "nodejs", reason="Not implemented")
@missing_feature(context.library < "nodejs@5.3.0", reason="Implemented in 3.48.0, 4.27.0, and 5.3.0")
@missing_feature(context.library == "ruby", reason="Not implemented")
@missing_feature(context.library == "php", reason="Not implemented")
def test_otel_span_started_with_link_from_another_span(self, test_agent, test_library):
Expand Down Expand Up @@ -448,7 +448,7 @@ def test_otel_span_started_with_link_from_another_span(self, test_agent, test_li
@missing_feature(context.library == "dotnet", reason="Not implemented")
@missing_feature(context.library < "[email protected]", reason="Implemented in 1.26.0")
@missing_feature(context.library == "golang", reason="Not implemented")
@missing_feature(context.library == "nodejs", reason="Not implemented")
@missing_feature(context.library < "nodejs@5.3.0", reason="Implemented in 3.48.0, 4.27.0, and 5.3.0")
@missing_feature(context.library < "[email protected]", reason="Not implemented")
@missing_feature(context.library == "php", reason="Not implemented")
def test_otel_span_started_with_link_from_datadog_headers(self, test_agent, test_library):
Expand Down Expand Up @@ -499,7 +499,7 @@ def test_otel_span_started_with_link_from_datadog_headers(self, test_agent, test
@missing_feature(context.library == "dotnet", reason="Not implemented")
@missing_feature(context.library < "[email protected]", reason="Implemented in 1.28.0")
@missing_feature(context.library == "golang", reason="Not implemented")
@missing_feature(context.library == "nodejs", reason="Not implemented")
@missing_feature(context.library < "nodejs@5.3.0", reason="Implemented in 3.48.0, 4.27.0, and 5.3.0")
@missing_feature(context.library < "[email protected]", reason="Not implemented")
@missing_feature(context.library == "php", reason="Not implemented")
def test_otel_span_started_with_link_from_w3c_headers(self, test_agent, test_library):
Expand Down Expand Up @@ -547,7 +547,7 @@ def test_otel_span_started_with_link_from_w3c_headers(self, test_agent, test_lib
@missing_feature(context.library == "dotnet", reason="Not implemented")
@missing_feature(context.library < "[email protected]", reason="Implemented in 1.26.0")
@missing_feature(context.library == "golang", reason="Not implemented")
@missing_feature(context.library == "nodejs", reason="Not implemented")
@missing_feature(context.library < "nodejs@5.3.0", reason="Implemented in 3.48.0, 4.27.0, and 5.3.0")
@missing_feature(context.library < "[email protected]", reason="Not implemented")
@missing_feature(context.library == "php", reason="Not implemented")
def test_otel_span_started_with_link_from_other_spans(self, test_agent, test_library):
Expand Down
9 changes: 7 additions & 2 deletions tests/parametric/test_span_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@scenarios.parametric
class Test_Span_Links:
@pytest.mark.parametrize("library_env", [{"DD_TRACE_API_VERSION": "v0.4"}])
@missing_feature(library="nodejs", reason="only supports span links encoding through _dd.span_links tag")
def test_span_started_with_link_v04(self, test_agent, test_library):
"""Test adding a span link created from another span and serialized in the expected v0.4 format.
This tests the functionality of "create a direct link between two spans
Expand Down Expand Up @@ -83,6 +84,9 @@ def test_span_started_with_link_v05(self, test_agent, test_library):
assert link["attributes"].get("array.1") == "b"
assert link["attributes"].get("array.2") == "c"

@missing_feature(
library="nodejs", reason="does not currently support creating a link from distributed datadog headers"
)
def test_span_link_from_distributed_datadog_headers(self, test_agent, test_library):
"""Properly inject datadog distributed tracing information into span links when trace_api is v0.4.
Testing the conversion of x-datadog-* headers to tracestate for
Expand Down Expand Up @@ -208,8 +212,9 @@ def test_span_with_attached_links(self, test_agent, test_library):
assert link["attributes"].get("nested.0") == "1"
assert link["attributes"].get("nested.1") == "2"

@missing_feature(library="python", reason="links do not influence the sampling decsion of spans")
@missing_feature(library="ruby", reason="links do not influence the sampling decsion of spans")
@missing_feature(library="python", reason="links do not influence the sampling decision of spans")
@missing_feature(library="nodejs", reason="links do not influence the sampling decision of spans")
@missing_feature(library="ruby", reason="links do not influence the sampling decision of spans")
def test_span_link_propagated_sampling_decisions(self, test_agent, test_library):
"""Sampling decisions made by an upstream span should be propagated via span links to
downstream spans.
Expand Down
53 changes: 47 additions & 6 deletions utils/build/docker/nodejs/parametric/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,49 @@ app.post('/trace/span/start', (req, res) => {
for (const [key, value] of http_headers) {
convertedHeaders[key.toLowerCase()] = value
}

const extracted = tracer.extract('http_headers', convertedHeaders)
if (extracted !== null) parent = extracted

const span = tracer.startSpan(request.name, {
type: request.type,
resource: request.resource,
childOf: parent,
tags: {
service: request.service
}
type: request.type,
resource: request.resource,
childOf: parent,
tags: {
service: request.service
}
})

for (const link of request.links || []) {
const linkParentId = link.parent_id;
if (linkParentId) {
const linkParentSpan = spans[linkParentId];
span.addLink(linkParentSpan.context(), link.attributes);
} else {
const linkHeaders = link.http_headers || {};
const convertedLinkHeaders = {}
for (const [key, value] of linkHeaders) {
convertedLinkHeaders[key.toLowerCase()] = value
}
const linkExtracted = tracer.extract('http_headers', convertedLinkHeaders);
if (linkExtracted) {
span.addLink(linkExtracted, link.attributes);
}
}
}

spans[span.context().toSpanId()] = span
res.json({ span_id: span.context().toSpanId(), trace_id:span.context().toTraceId(), service:request.service, resource:request.resource,});
});

app.post('/trace/span/add_link', (req, res) => {
const request = req.body;
const span = spans[request.span_id]
const linked_span = spans[request.parent_id]
span.addLink(linked_span.context(), request.attributes)
res.json({});
});

app.post('/trace/span/finish', (req, res) => {
const id = req.body.span_id
const span = spans[id]
Expand Down Expand Up @@ -147,10 +175,23 @@ app.post('/trace/otel/start_span', (req, res) => {

const makeSpan = (parentContext) => {

const links = (request.links || []).map(link => {
let spanContext;
if (link.parent_id && link.parent_id !== 0) {
spanContext = otelSpans[link.parent_id].spanContext();
} else {
const linkHeaders = Object.fromEntries(link.http_headers.map(([k, v]) => [k.toLowerCase(), v]));
const extractedContext = tracer.extract('http_headers', linkHeaders)
spanContext = new OtelSpanContext(extractedContext)
}
return {context: spanContext, attributes: link.attributes}
});

const span = otelTracer.startSpan(request.name, {
type: request.type,
kind: request.kind,
attributes: request.attributes,
links,
startTime: nanoLongToHrTime(request.timestamp)
}, parentContext)
const ctx = span._ddSpan.context()
Expand Down

0 comments on commit cfbe667

Please sign in to comment.