Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trace-per-test option #34

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

xmo-odoo
Copy link

Trace-per-run is not always great e.g. it's confusing to have a sequence of tests which are normally independent, and then the layout changes when xdist is involved as you get concurrent spans (one for each worker).

This also causes issues in the more bare-bone / simplistic frontends / final collectors (e.g. OpenTelemetry Desktop) as they might not have the most complex folding and filtering features. OTD for instance has little to no ability to manipulate spans, but it is possible to select individual traces and see just that trace's spans (in fact that's the only mode).

As a result, generating a separate trace per test per run allows easier classification, observation, and manipulation of the trace. I would also assume in the long term it allows comparing the traces of the same test in order to get insight into their evolution, something which is more difficult with trace-per-run.

Finally an other issue with trace-per-run, mostly in long suites, is that the trace remains incomplete (tools complain of missing parent spans) until the entire run has completed, making observation during run more difficult.

Fixes #33

@chrisguidry
Copy link
Owner

@xmo-odoo I do like this idea, but would we really need a full new copy of the plugin? Could this be done conditionally?

@xmo-odoo
Copy link
Author

xmo-odoo commented Nov 25, 2024

I do like this idea, but would we really need a full new copy of the plugin? Could this be done conditionally?

There's no copy of the plugin? I did implement that initially locally as a test, but then realised the trace-per-test version was really just a subset of the trace-per-run version, so PerTestOpenTelemetryPlugin is really just extracted from OpenTelemetryPlugin: OpenTelemetryPlugin has 3 methods which aren't in PerTestOpenTelemetryPlugin at all, and two methods it needs to override to deal with has_error and the suite-level span.

Before this change, OpenTelemetryPlugin is 228 lines, after this change OpenTelemetryPlugin is 40 lines and PerTestOpenTelemetryPlugin is 203. So there is some overhead from an additional property and a pair of methods needing override, but not a copy.

I'm not sure adding an __init__ and conditions in every relevant method would be significantly shorter, or easier to understand. Especially as the per-test version doesn't need an xdist case.

@chrisguidry
Copy link
Owner

I'll buy that! Just looks like we're missing one line of coverage for the item_parent property, should be easy to add. Thanks!

@xmo-odoo
Copy link
Author

xmo-odoo commented Dec 3, 2024

Just looks like we're missing one line of coverage for the item_parent property, should be easy to add. Thanks!

Yep, I'll take a gander as how things are tested.

@xmo-odoo xmo-odoo force-pushed the trace-per-test branch 2 times, most recently from 494e1a9 to 3ab38a0 Compare December 3, 2024 09:16
@xmo-odoo
Copy link
Author

xmo-odoo commented Dec 3, 2024

I added a test for the trace-per-test mode, however it doesn't look like pytest-cov sees the code run by runpytest_subprocess for some reason (if I add prints in the property they do fire, so it's not that that code is not exercised, just not recorded), so I'm not too sure what to do. I could always hand-instantiate the plugin with various configs and check that the item_parent is consistent but that feels dubious.

Also not sure the test is very valuable. I wanted to check that the $TEST::call span's parent was $TEST whose parent was the traceparent's (and check for the intermediate xdist and run-level spans in the existing tests) however I was not able to find how to "climb" the span tree in the otel API. I suspect it's not possible without dedicated instrumentation because the stack is hidden behind the contextvar of ContextVarsRuntimeContext, but I don't really have a grasp on the otel sdk.

@xmo-odoo xmo-odoo mentioned this pull request Feb 24, 2025
13 tasks
@xmo-odoo xmo-odoo force-pushed the trace-per-test branch 2 times, most recently from 7c5fd04 to 0a06f05 Compare February 24, 2025 12:03
Trace-per-run is not always great e.g. it's confusing to have a
sequence of tests which are normally independent, and then the layout
changes when xdist is involved as you get concurrent spans (one for
each worker).

This also causes issues in the more bare-bone / simplistic frontends /
final collectors (e.g. OpenTelemetry Desktop) as they might not have
the most complex folding and filtering features. OTD for instance has
little to no ability to manipulate spans, but it is possible to select
individual traces and see just that trace's spans (in fact that's the
only mode).

As a result, generating a separate trace per test per run allows
easier classification, observation, and manipulation of the trace. I
would also assume in the long term it allows comparing the traces of
the same test in order to get insight into their evolution, something
which is more difficult with trace-per-run.

Finally an other issue with trace-per-run, mostly in long suites, is
that the trace remains incomplete (tools complain of missing parent
spans) until the entire run has completed, making observation during
run more difficult.
@xmo-odoo
Copy link
Author

xmo-odoo commented Feb 24, 2025

Finally got around to looking into the coverage issue (sorry) I can confirm that coverage does not see the runpytest_subprocess for some reason, and trying to configure tool.coverage.run based on the documentation of pytest-cov and / or coverage didn't resolve the issue.

So in order to get coverage, I parametrized one of the span tests to run in both trace-per-suite and trace-per-test modes. I think technically all the tests could be parametrized thus (or near enough) but every other tests specifically checks for the test run span so requires a lot more work to parametrize.

xmo-odoo added a commit to odoo/runbot that referenced this pull request Feb 24, 2025
Mostly for tests: it can be really difficult to correlate issues as
there are 3 different processes involved (the test runner, the odoo
being tested, and dummy-central (as github)) and the intermixing of
logs between the test driver and the odoo being tested is
not *amazing*.

- `pytest-opentelemetry`'s `--export-traces` is the signal for running
  tests with tracing enabled, that way just having
  `pytest-opentelemetry` installed does not do anything untowards.
- Until chrisguidry/pytest-opentelemetry#34 is merged, should probably
  use the linked branch as the default / base mode of having a single
  trace for the entire test suite is not great when there are 460
  tests, especially as local clients (opentelemetry-desktop-viewer,
  venator) mostly work on traces and aren't very good at zooming on
  *spans* at least currently.
- Additionally, the conftest plugin adds hooks for propagating through
  the xmlrpc client (communications with odoo) and enables the
  requests instrumentor from the opentelemetry python contribs.
- The dummy `saas_worker` was moved into the filesystem, that makes it
  easier to review and update.
- A second such module was added for the otel instrumentation *of the
  odoo under test*, that instruments psycopg2, requests, wsgi, and the
  server side of xmlrpc.
- The git ops were instrumented directly in runbot_merge, as I've
  tried to keep `saas_tracing` relatively generic, in case it could be
  moved to community or used by internal eventually.

Some typing was added to the conftest hooks and fixtures, and they
were migrated from tmpdir (py.path) to tmp_path (pathlib) for
consistency, even though technically the `mkdir` of pathlib is an
annoying downgrade.

Fixes #835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

trace-per-test mode?
2 participants