Skip to content

[FEAT]: Stream xdist results through test reports - #166

Merged
Nina Chikanov (nina-msft) merged 6 commits into
microsoft:mainfrom
nina-msft:nina-msft-stream-xdist-results
Aug 17, 2026
Merged

[FEAT]: Stream xdist results through test reports#166
Nina Chikanov (nina-msft) merged 6 commits into
microsoft:mainfrom
nina-msft:nina-msft-stream-xdist-results

Conversation

@nina-msft

@nina-msft Nina Chikanov (nina-msft) commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Description

The previous end-of-worker xdist batch could lose every Result from a worker that crashed before session finish and applied the size cap to the worker payload as a whole. This PR replaces that batch with incremental call-report streaming so the controller retains each Result as soon as its TestReport arrives.

This builds on the collector call-phase snapshot delivered by #152, which is now merged into main.

Approach

  • Workers attach an execnet-safe JSON envelope to call-phase TestReports using the existing full-fidelity Result serializer.
  • The controller validates and merges envelopes in pytest_runtest_logreport, tags source workers, and preserves deterministic ordering, including --dist=each.
  • Workeroutput contains only trial specifications and the expected streamed Result count. Node-down reconciliation marks missing output, missing counts, mismatches, and worker errors incomplete without discarding Results already received.
  • The cap of 16 MiB applies independently to each Result. Oversized Results become attributed ERROR markers while normal Results continue to stream. A 4 KiB effective minimum and JSON-byte bounds guarantee markers fit, including control and non-BMP Unicode attribution.
  • The transport schema and workeroutput key move to v2 so protocol skew fails closed.
  • Results recorded only during fixture teardown remain intentionally outside the call-phase transport.

A killed worker retains every Result already delivered to the controller. The repository harness does not provide a deterministic remote/non-popen gateway, so that topology remains a residual integration risk.

Validation

  • python -m pytest tests\unit\pytest_plugin -q - 198 passed
  • Focused streamed transport and real-xdist coverage - 95 passed
  • Adversarial control/non-BMP cap coverage - 2 passed
  • ruff check .
  • ruff format --check .
  • Repository-wide ty check

Breaking changes

None. Mixed worker/controller transport versions remain unsupported and now fail closed under the v2 schema.

Checklist

  • pre-commit run --all-files passes
  • Tests added or updated for report streaming, async/call boundaries, slim workeroutput, reconciliation, crash durability, ordering, protocol skew, and per-Result caps
  • Documentation updated

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0ab46710-f0d9-4941-bbd5-eac658126165
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0ab46710-f0d9-4941-bbd5-eac658126165

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Streams xdist Results incrementally through call-phase reports, preserving delivered Results after worker failures.

Changes:

  • Adds per-Result serialization, validation, size caps, and controller merging.
  • Reconciles streamed counts during worker shutdown.
  • Expands tests and documentation for durability, ordering, and truncation.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
rampart/pytest_plugin/_xdist.py Implements streamed transport and reconciliation.
rampart/pytest_plugin/plugin.py Integrates streaming with pytest hooks.
rampart/pytest_plugin/_session.py Extracts result tagging and deduplicates incomplete reasons.
tests/unit/pytest_plugin/test_xdist.py Tests serialization, validation, caps, and reconciliation.
tests/unit/pytest_plugin/test_xdist_aggregation.py Adds real-xdist streaming integration tests.
tests/unit/pytest_plugin/test_plugin.py Tests worker attachment and controller merging hooks.
docs/usage/xdist.md Documents streamed transport behavior.
docs/usage/configuration.md Updates size-cap configuration.
docs/usage/ci-integration.md Updates CI option guidance.
docs/contributing/architecture.md Revises plugin architecture documentation.
docs/api/pytest-plugin.md Updates documented xdist APIs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rampart/pytest_plugin/_xdist.py Outdated
Comment thread tests/unit/pytest_plugin/test_xdist_aggregation.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread rampart/pytest_plugin/_session.py Outdated
Comment thread rampart/pytest_plugin/_xdist.py Outdated
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/_xdist.py
Comment thread rampart/pytest_plugin/plugin.py
Use pytest item display names for Result metadata and resolve the xdist transport cap once per report envelope.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0ab46710-f0d9-4941-bbd5-eac658126165
@nina-msft
Nina Chikanov (nina-msft) marked this pull request as ready for review August 14, 2026 19:43
@nina-msft
Nina Chikanov (nina-msft) requested a review from a team August 14, 2026 19:43
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (1)

rampart/pytest_plugin/plugin.py:499

  • A fixture can record a Result and then fail or skip during setup. Pytest emits no call-phase report in that case, so this branch never transports the collected Result. The worker consequently publishes an emitted count of zero, which matches the controller's zero and silently produces a complete-looking report with the Result missing. Stream the active collector on non-passing setup reports (while retaining call-only streaming for successful setup) or otherwise reconcile collected versus emitted Results.
        collector = get_active_collector()

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0ab46710-f0d9-4941-bbd5-eac658126165
Stream setup-recorded Results on failed or skipped setup reports while deferring successful setup Results to the call report and keeping teardown outside transport.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0ab46710-f0d9-4941-bbd5-eac658126165

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it fits, it ships! 📦🚀

@nina-msft
Nina Chikanov (nina-msft) merged commit 3e70958 into microsoft:main Aug 17, 2026
14 checks passed
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.

3 participants