Add integration tests for ASGI Django 3#2640
Conversation
5a1c530 to
ee17085
Compare
There was a problem hiding this comment.
Introduce an endpoint to force a flush of the traces to reduce this flakiness. Thanks @P403n1x87!
There was a problem hiding this comment.
Interesting idea! We'd want to disable tracing for such an endpoint so we don't end up getting it's trace in the snapshot as well.
There was a problem hiding this comment.
Another option would be to have the client fixture be per test such that flushing occurs during shutdown.
There was a problem hiding this comment.
We'd want to disable tracing for such an endpoint so we don't end up getting it's trace in the snapshot as well.
Ah yes... good point!
Another option would be to have the client fixture be per test such that flushing occurs during shutdown.
yes - this would be more ideal IMO but there is a non-trivial cost of starting up the webserver unfortunately... although we don't run a lot of test scenarios
There was a problem hiding this comment.
glad to say that all the time.sleep()s have been purged! Instead,
- the django instance is started per process
- traces are sent with a test token directly thanks to Add internal setting for additional writer headers #2689
- polling spans are filtered by using http propagation headers with a special trace id
TraceFilterfilters traces with the special trace id- traces are force-flushed with a call to a special endpoint
dab0c2e to
b9dc65c
Compare
Add integration tests which run a real Django instance using ASGI and daphne.
2d3ee99 to
0bc3679
Compare
For testing it's desirable to be able to pass additional headers with the trace requests made to the agent. With this ability we can propagate tokens which can be used to associate traces with test cases when running snapshot tests in subprocesses (like in DataDog#2640). I debated having the flag be read at run-time instead of initialization-time but opted against it as reading from the env is not cheap (on the order of 1µs): >>> %timeit os.environ.get("") 1.23 µs ± 49.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
For testing it's desirable to be able to pass additional headers with the trace requests made to the agent. With this ability we can propagate tokens which can be used to associate traces with test cases when running snapshot tests in subprocesses (like in #2640). I debated having the flag be read at run-time instead of initialization-time but opted against it as reading from the env is not cheap (on the order of 1µs): >>> %timeit os.environ.get("") 1.23 µs ± 49.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1baaba9 to
ceed6ca
Compare
a7a71a1 to
6f399d1
Compare
23fd044 to
cceca3a
Compare
| from ddtrace.contrib.asgi import TraceMiddleware | ||
|
|
||
|
|
||
| application = TraceMiddleware(get_asgi_application()) |
There was a problem hiding this comment.
is this what we are recommending for customers to do now?
There was a problem hiding this comment.
A bit of a long story.... because of #2559 there's no way to be able to identify traces as coming from a particular route (no route tagging, no http propagation, no query params, etc) in order to filter traces that we don't care about (polling, startup, teardown, etc).
I added in the ASGI middleware to mitigate this for now so that we don't get a bunch of flaky time.sleep()s everywhere.
I think it's ok because the ASGI spans just wrap the Django ones. With #2656 we'll remove this explicit usage.
a9838ac to
3cab2b9
Compare
Avoid the redirect
|
LGTM |
Add integration tests which run a real Django instance using ASGI
and daphne.
A new function-scope
daphne_clientfixture is introduced whichinitializes a real
daphneDjango server using the one in ourtest suite. The client fixture provides an API to query the server much
like the pytest Django client.
Traces from the test cases are captured with the test agent and
snapshotted. Traces produced as a part of setup and teardown
are sent with distributed tracing headers which assign a trace id
of
1which an installedTraceFilterwill filter out.Any temporal dependency is removed by adding a special shutdown
endpoint to the Django app which does a
tracer.shutdown()to flushthe traces for the test case.