Skip to content

Commit

Permalink
chore(otel): fix flakies (#10797)
Browse files Browse the repository at this point in the history
## Checklist
- [x] PR author has checked that all the criteria below are met
- The PR description includes an overview of the change
- The PR description articulates the motivation for the change
- The change includes tests OR the PR description describes a testing
strategy
- The PR description notes risks associated with the change, if any
- Newly-added code is easy to change
- The change follows the [library release note
guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html)
- The change includes or references documentation updates if necessary
- Backport labels are set (if
[applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting))

## Reviewer Checklist
- [x] Reviewer has checked that all the criteria below are met 
- Title is accurate
- All changes are related to the pull request's stated goal
- Avoids breaking
[API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces)
changes
- Testing strategy adequately addresses listed risks
- Newly-added code is easy to change
- Release note makes sense to a user of the library
- If necessary, author has acknowledged and discussed the performance
implications of this PR as reported in the benchmarks PR comment
- Backport labels are set in a manner that is consistent with the
[release branch maintenance
policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
  • Loading branch information
mabdinur authored Oct 1, 2024
1 parent ade370a commit 5ac9704
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 54 deletions.
4 changes: 4 additions & 0 deletions riotfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,10 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION):
name="opentelemetry",
command="pytest {cmdargs} tests/opentelemetry",
pys=select_pys(min_version="3.8"),
# DD_TRACE_OTEL_ENABLED must be set to true before ddtrace is imported
# and ddtrace (ddtrace.config specifically) must be imported before opentelemetry.
# If this order is violated otel and datadog spans will not be interoperable.
env={"DD_TRACE_OTEL_ENABLED": "true"},
pkgs={
"pytest-randomly": latest,
"pytest-asyncio": "==0.21.1",
Expand Down
3 changes: 0 additions & 3 deletions tests/opentelemetry/flask_app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import sys

import flask
Expand All @@ -9,8 +8,6 @@
from tests.webclient import PingFilter


# Enable ddtrace context management and set the datadog tracer provider
os.environ["OTEL_PYTHON_CONTEXT"] = "ddcontextvars_context"
opentelemetry.trace.set_tracer_provider(TracerProvider())

ddtrace.tracer.configure(settings={"FILTERS": [PingFilter()]})
Expand Down
2 changes: 1 addition & 1 deletion tests/opentelemetry/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def test_otel_sdk_disabled_configuration():
assert config._otel_enabled is True


@pytest.mark.subprocess(env={"OTEL_SDK_DISABLED": "true"})
@pytest.mark.subprocess(env={"OTEL_SDK_DISABLED": "true", "DD_TRACE_OTEL_ENABLED": ""})
def test_otel_sdk_disabled_configuration_true():
from ddtrace import config

Expand Down
2 changes: 0 additions & 2 deletions tests/opentelemetry/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import ddtrace
from ddtrace.constants import MANUAL_DROP_KEY
from ddtrace.constants import MANUAL_KEEP_KEY
from tests.utils import flaky


@pytest.mark.snapshot
Expand All @@ -34,7 +33,6 @@ def test_otel_span_parenting(oteltracer):
orphan1.end()


@flaky(1735812000)
@pytest.mark.snapshot
def test_otel_ddtrace_mixed_parenting(oteltracer):
with oteltracer.start_as_current_span("otel-top-level"):
Expand Down
24 changes: 11 additions & 13 deletions tests/opentelemetry/test_span.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

from ddtrace.constants import MANUAL_DROP_KEY
from ddtrace.internal.opentelemetry.span import Span
from tests.utils import flaky


@pytest.mark.snapshot(wait_for_num_traces=3)
Expand Down Expand Up @@ -82,7 +81,6 @@ def test_otel_span_attributes_overrides(oteltracer, override):
span.set_attribute(otel, value)


@flaky(1735812000)
@pytest.mark.snapshot
def test_otel_span_kind(oteltracer):
with oteltracer.start_span("otel-client", kind=OtelSpanKind.CLIENT):
Expand Down Expand Up @@ -236,11 +234,11 @@ def test_otel_get_span_context_with_multiple_tracesates(oteltracer):


def test_otel_get_span_context_with_default_trace_state(oteltracer):
otelspan = oteltracer.start_span("otel-server")
otelspan.set_attribute(MANUAL_DROP_KEY, "")
with oteltracer.start_span("otel-server") as otelspan:
otelspan.set_attribute(MANUAL_DROP_KEY, "")

span_context = otelspan.get_span_context()
assert span_context.trace_flags == TraceFlags.DEFAULT
span_context = otelspan.get_span_context()
assert span_context.trace_flags == TraceFlags.DEFAULT


@pytest.mark.parametrize("trace_flags", [TraceFlags.SAMPLED, TraceFlags.DEFAULT])
Expand All @@ -261,17 +259,17 @@ def test_otel_span_with_remote_parent(oteltracer, trace_flags, trace_state):
def test_otel_span_interoperability(oteltracer):
"""Ensures that opentelemetry spans can be converted to ddtrace spans"""
# Start an otel span
otel_span_og = oteltracer.start_span(
with oteltracer.start_span(
"test-span-interop",
links=[Link(SpanContext(1, 2, False, None, None))],
kind=OtelSpanKind.CLIENT,
attributes={"start_span_tag": "start_span_val"},
start_time=1713118129,
record_exception=False,
set_status_on_exception=False,
)
# Creates a new otel span from the underlying datadog span
otel_span_clone = Span(otel_span_og._ddspan)
# Ensure all properties are consistent
assert otel_span_clone.__dict__ == otel_span_og.__dict__
assert otel_span_clone._ddspan._pprint() == otel_span_og._ddspan._pprint()
) as otel_span_og:
# Creates a new otel span from the underlying datadog span
otel_span_clone = Span(otel_span_og._ddspan)
# Ensure all properties are consistent
assert otel_span_clone.__dict__ == otel_span_og.__dict__
assert otel_span_clone._ddspan._pprint() == otel_span_og._ddspan._pprint()
70 changes: 39 additions & 31 deletions tests/opentelemetry/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from ddtrace.internal.utils.version import parse_version
from tests.contrib.flask.test_flask_snapshot import flask_client # noqa:F401
from tests.contrib.flask.test_flask_snapshot import flask_default_env # noqa:F401
from tests.utils import flaky


OTEL_VERSION = parse_version(opentelemetry.version.__version__)
Expand Down Expand Up @@ -76,29 +75,33 @@ def test_otel_start_span_without_default_args(oteltracer):
def test_otel_start_span_with_span_links(oteltracer):
# create a span and generate an otel link object
span1 = oteltracer.start_span("span-1")
span1_context = span1.get_span_context()
attributes1 = {"attr1": 1, "link.name": "moon"}
link_from_span_1 = opentelemetry.trace.Link(span1_context, attributes1)
# create another span and generate an otel link object
span2 = oteltracer.start_span("span-2")
span2_context = span2.get_span_context()
attributes2 = {"attr2": 2, "link.name": "tree"}
link_from_span_2 = opentelemetry.trace.Link(span2_context, attributes2)

# create an otel span that links to span1 and span2
with oteltracer.start_as_current_span("span-3", links=[link_from_span_1, link_from_span_2]) as span3:
pass

# assert that span3 has the expected links
ddspan3 = span3._ddspan
for span_context, attributes in ((span1_context, attributes1), (span2_context, attributes2)):
[link, *others] = [link for link in ddspan3._links if link.span_id == span_context.span_id]
assert not others
assert link.trace_id == span_context.trace_id
assert link.span_id == span_context.span_id
assert link.tracestate == span_context.trace_state.to_header()
assert link.flags == span_context.trace_flags
assert link.attributes == attributes

try:
span1_context = span1.get_span_context()
attributes1 = {"attr1": 1, "link.name": "moon"}
link_from_span_1 = opentelemetry.trace.Link(span1_context, attributes1)
span2_context = span2.get_span_context()
attributes2 = {"attr2": 2, "link.name": "tree"}
link_from_span_2 = opentelemetry.trace.Link(span2_context, attributes2)

# create an otel span that links to span1 and span2
with oteltracer.start_as_current_span("span-3", links=[link_from_span_1, link_from_span_2]) as span3:
pass

# assert that span3 has the expected links
ddspan3 = span3._ddspan
for span_context, attributes in ((span1_context, attributes1), (span2_context, attributes2)):
[link, *others] = [link for link in ddspan3._links if link.span_id == span_context.span_id]
assert not others
assert link.trace_id == span_context.trace_id
assert link.span_id == span_context.span_id
assert link.tracestate == span_context.trace_state.to_header()
assert link.flags == span_context.trace_flags
assert link.attributes == attributes
finally:
span1.end()
span2.end()


@pytest.mark.snapshot(ignores=["meta.error.stack"])
Expand Down Expand Up @@ -185,23 +188,28 @@ def test_distributed_trace_extract(oteltracer): # noqa:F811
assert sp.is_remote is False


@flaky(1717428664)
def otel_flask_app_env(flask_wsgi_application):
env = flask_default_env(flask_wsgi_application)
env.update({"DD_TRACE_OTEL_ENABLED": "true"})
return env


@pytest.mark.parametrize(
"flask_wsgi_application,flask_env_arg,flask_port,flask_command",
[
(
"tests.opentelemetry.flask_app:app",
flask_default_env,
"8000",
["ddtrace-run", "flask", "run", "-h", "0.0.0.0", "-p", "8000"],
otel_flask_app_env,
"8010",
["ddtrace-run", "flask", "run", "-h", "0.0.0.0", "-p", "8010"],
),
pytest.param(
"tests.opentelemetry.flask_app:app",
flask_default_env,
"8001",
["opentelemetry-instrument", "flask", "run", "-h", "0.0.0.0", "-p", "8001"],
otel_flask_app_env,
"8011",
["opentelemetry-instrument", "flask", "run", "-h", "0.0.0.0", "-p", "8011"],
marks=pytest.mark.skipif(
OTEL_VERSION < (1, 12),
OTEL_VERSION < (1, 16),
reason="otel flask instrumentation is in beta and is unstable with earlier versions of the api",
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"http.method": "GET",
"http.route": "/otel",
"http.status_code": "200",
"http.url": "http://0.0.0.0:8000/otel",
"http.url": "http://0.0.0.0:8010/otel",
"http.useragent": "python-requests/2.28.1",
"language": "python",
"runtime-id": "a29fc1c052394690a557d5d7a5207798",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"_dd.p.tid": "66a666b600000000",
"_dd.parent_id": "ae6e2bf21738f62f",
"http.flavor": "1.1",
"http.host": "0.0.0.0:8001",
"http.host": "0.0.0.0:8011",
"http.method": "GET",
"http.route": "/otel",
"http.scheme": "http",
Expand All @@ -46,7 +46,7 @@
"http.target": "/otel",
"http.user_agent": "python-requests/2.28.1",
"language": "python",
"net.host.name": "0.0.0.0:8001",
"net.host.name": "0.0.0.0:8011",
"net.peer.ip": "127.0.0.1",
"runtime-id": "0dacca250fe4471094dc593f4892b91f",
"span.kind": "server",
Expand All @@ -56,7 +56,7 @@
"_dd.top_level": 1,
"_dd.tracer_kr": 1.0,
"_sampling_priority_v1": 1,
"net.host.port": 8001,
"net.host.port": 8011,
"net.peer.port": 62683,
"process_id": 75530
},
Expand Down

0 comments on commit 5ac9704

Please sign in to comment.