Skip to content

Remove Windows xfail hook for rust-build-release smoke tests#107

Merged
leynos merged 3 commits intomainfrom
codex/remove-xfail-annotations-from-windows-tests
Sep 21, 2025
Merged

Remove Windows xfail hook for rust-build-release smoke tests#107
leynos merged 3 commits intomainfrom
codex/remove-xfail-annotations-from-windows-tests

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Sep 21, 2025

Summary

Testing

  • make test

https://chatgpt.com/codex/tasks/task_e_68d00dd8a59883228495dbeb49eac141

Summary by Sourcery

Tests:

  • Eliminate the pytest_collection_modifyitems logic that filtered out xfail marks for the Windows smoke test

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 21, 2025

Summary by CodeRabbit

  • New Features
    • No user-facing changes.
  • Tests
    • Windows smoke test is no longer treated as an expected failure, with legacy markers filtered during test collection for accurate pass/fail reporting on Windows.
  • Chores
    • Streamlined CI test handling on Windows to reduce noise from outdated markers and improve reliability of release validation.
  • Notes
    • No impact on product behaviour; end users are unaffected.

Summary by CodeRabbit

  • Tests
    • Update Windows smoke test handling to remove outdated expected-failure markers, ensuring accurate pass/fail reporting on Windows.
    • Filter legacy markers during test collection to improve CI stability and clarity.
    • Do not change product behaviour; adjust only test collection to improve Windows validation.

Walkthrough

Add two constants and a pytest collection hook in .github/actions/rust-build-release/tests/conftest.py to strip legacy xfail marks matching a specific reason from a Windows smoke test.

Changes

Cohort / File(s) Summary
Test infra: Windows smoke xfail filtering
.github/actions/rust-build-release/tests/conftest.py
Add WINDOWS_SMOKE_TEST: str and WINDOWS_XFAIL_REASON: str. Implement pytest_collection_modifyitems(config, items) to remove xfail marks whose reason equals WINDOWS_XFAIL_REASON for the WINDOWS_SMOKE_TEST, so the test no longer carries the legacy xfail.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Pytest as Pytest Runner
  participant Hook as conftest.py::pytest_collection_modifyitems
  participant Items as Collected Tests

  Pytest->>Items: Collect tests
  Pytest->>Hook: Call pytest_collection_modifyitems(config, items)
  note right of Hook: Identify items matching WINDOWS_SMOKE_TEST<br/>and xfail marks with WINDOWS_XFAIL_REASON
  Hook->>Items: Remove matching xfail marks
  Pytest->>Items: Run tests with updated marks
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A Windows wisp, an xfail’s trace,
The hook steps in to clean the place.
Two constants guard the smoky gate,
Old reasons trimmed, a tidier state.
Pytest marches, marks made right—green lights in sight.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive Mark this check as inconclusive; the change removes the legacy xfail for the Windows rust-build-release smoke test and therefore targets the linked issue's intent, but the implementation still mutates item.own_markers via slice assignment instead of using pytest marker APIs and thus fails to meet the coding-quality recommendations in the PR comments, and it is unclear whether the underlying Docker timeout is resolved without running Windows CI. Replace the slice-assignment mutation with explicit item.remove_marker(marker) calls for each matched xfail, re-run Windows CI to confirm Docker timeouts are resolved, and update the PR description with the CI outcome before closing issue #93.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed Approve the title; it succinctly and accurately summarises the primary change (removing the Windows xfail hook for rust-build-release smoke tests) and aligns with the modifications in .github/actions/rust-build-release/tests/conftest.py.
Out of Scope Changes Check ✅ Passed Approve as in-scope; the changes are confined to .github/actions/rust-build-release/tests/conftest.py and directly address xfail handling for the Windows smoke test with no unrelated files modified.
Description Check ✅ Passed Accept the description; it directly relates to the changeset, references issue #93, and documents the testing step (make test).
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/remove-xfail-annotations-from-windows-tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Ruff (0.13.1)
.github/actions/rust-build-release/tests/conftest.py

�[1;31mruff failed�[0m
�[1mCause:�[0m Failed to load configuration /ruff.toml
�[1mCause:�[0m Failed to parse /ruff.toml
�[1mCause:�[0m TOML parse error at line 26, column 3
|
26 | "RSE100", # Use of assert detected
| ^^^^^^^^
Unknown rule selector: RSE100


Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Sep 21, 2025

Reviewer's Guide

Updated pytest configuration to drop the legacy Windows xfail mark on the rust-build-release smoke test, allowing it to pass normally on Windows.

File-Level Changes

Change Details Files
Remove legacy xfail handling for Windows smoke test
  • Define constants for the smoke test name and its xfail reason
  • Add pytest_collection_modifyitems hook to strip xfail marks matching the Windows reason
  • Ensure only the targeted test on Windows has its xfail mark removed
.github/actions/rust-build-release/tests/conftest.py

Assessment against linked issues

Issue Objective Addressed Explanation
#93 Fix the Windows CI rust-build-release smoke test failures caused by Docker command timeouts. The PR only removes the legacy xfail mark for the Windows smoke tests, allowing them to run and potentially pass if the underlying issue is resolved. However, it does not address the root cause of the Docker command timeouts or make any changes to the CI configuration, Docker setup, or test logic to fix the timeout failures themselves.
#93 Ensure that the Windows smoke tests for rust-build-release pass reliably in CI by resolving the Docker timeout issue. The PR does not implement any changes to resolve the Docker timeout issue. It simply removes the xfail mark, which may allow tests to run and pass if the environment is fixed elsewhere, but does not itself ensure reliable passing of the tests by fixing the timeout problem.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Instead of mutating item.own_markers directly, use pytest's marker APIs (like item.remove_marker or item.get_closest_marker) to remove the xfail mark more explicitly and maintain compatibility with future pytest versions.
  • Hardcoding the test function name and checking for 'windows' in item.name might be brittle; consider matching on the xfail marker itself or using nodeid patterns to target this test removal more robustly.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Instead of mutating item.own_markers directly, use pytest's marker APIs (like item.remove_marker or item.get_closest_marker) to remove the xfail mark more explicitly and maintain compatibility with future pytest versions.
- Hardcoding the test function name and checking for 'windows' in item.name might be brittle; consider matching on the xfail marker itself or using nodeid patterns to target this test removal more robustly.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cf6959 and 7492d35.

📒 Files selected for processing (1)
  • .github/actions/rust-build-release/tests/conftest.py (2 hunks)
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Sourcery review
  • GitHub Check: python-tests (ubuntu-latest)
  • GitHub Check: python-tests (windows-latest)
  • GitHub Check: build-release (windows-latest, x86_64-pc-windows-gnu)
  • GitHub Check: build-release (windows-latest, aarch64-pc-windows-gnu)
🔇 Additional comments (1)
.github/actions/rust-build-release/tests/conftest.py (1)

40-44: Keep the pinned test name and xfail reason as-is — verified

test_action_builds_release_binary_and_manpage exists in .github/actions/rust-build-release/tests/test_smoke.py (line 87). The xfail reason string matches the entry in .github/actions/rust-build-release/tests/conftest.py (lines 40–44).

Comment thread .github/actions/rust-build-release/tests/conftest.py Outdated
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 21, 2025

@coderabbitai Have the following now been resolved?

  • Instead of mutating item.own_markers directly, use pytest's marker APIs (like item.remove_marker or item.get_closest_marker) to remove the xfail mark more explicitly and maintain compatibility with future pytest versions.
  • Hardcoding the test function name and checking for 'windows' in item.name might be brittle; consider matching on the xfail marker itself or using nodeid patterns to target this test removal more robustly.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@leynos No, both concerns have not been resolved in the current implementation. Here's what I found:

1. Marker API usage issue - NOT RESOLVED:
The code still directly mutates item.own_markers using .clear() and .extend():

item.own_markers.clear()
item.own_markers.extend(filtered_markers)

This should use pytest's recommended marker APIs instead.

2. Hardcoded matching issue - NOT RESOLVED:
The code still uses hardcoded patterns:

WINDOWS_SMOKE_TEST = "test_action_builds_release_binary_and_manpage"
# ...and later:
if item.name == WINDOWS_SMOKE_TEST and "windows" in item.name:

Here's how to address both concerns:

def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
    """Remove legacy xfail marks for Windows smoke tests."""
    for item in items:
        # More robust: check for xfail markers with specific reason
        xfail_markers = [m for m in item.iter_markers("xfail")]
        
        for marker in xfail_markers:
            if marker.kwargs.get("reason") == WINDOWS_XFAIL_REASON:
                # Use pytest's marker API instead of direct mutation
                item.remove_marker(marker)

This approach:

  • Uses item.remove_marker() instead of direct mutation
  • Matches on the xfail marker reason rather than hardcoded test names
  • Is more robust and compatible with future pytest versions

🏁 Script executed:

#!/bin/bash
# Read the conftest.py file to examine the current implementation
cat .github/actions/rust-build-release/tests/conftest.py

Length of output: 9359


@leynos The implementation has been significantly improved and one concern has been largely resolved:

1. Marker API usage - PARTIALLY RESOLVED:
The code now uses item.iter_markers(name="xfail") which is part of pytest's marker API. However, it still uses direct mutation with slice assignment:

item.own_markers[:] = filtered_marks

While this is better than the previous .clear()/.extend() approach, it still directly mutates the markers list rather than using pytest's recommended item.remove_marker() API.

2. Hardcoded matching - LARGELY RESOLVED ✅:
This has been much improved! The code now:

  • Uses nodeid instead of item.name for more robust matching
  • Uses pattern-based checks (WINDOWS_SMOKE_TEST not in nodeid and "-pc-windows-" not in nodeid)
  • Matches on the xfail marker reason rather than just test names
  • Is much more flexible and maintainable

To fully resolve concern #1, you could use:

for mark in matching_xfails:
    item.remove_marker(mark)

But the current implementation is already much more robust than the original version. The nodeid-based pattern matching is particularly good as it properly targets the specific Windows test variants without brittle hardcoding.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7492d35 and 8e2274e.

📒 Files selected for processing (1)
  • .github/actions/rust-build-release/tests/conftest.py (2 hunks)
🧰 Additional context used
🔍 Remote MCP Ref

Additional context found (concluded)

  • File changed: .github/actions/rust-build-release/tests/conftest.py — adds WINDOWS_SMOKE_TEST, WINDOWS_XFAIL_REASON, and a pytest_collection_modifyitems hook that drops xfail marks whose reason equals WINDOWS_XFAIL_REASON to let the Windows rust-build-release smoke test run normally.

  • Implementation detail: the hook iterates item.iter_markers(name="xfail") and filters by marker.kwargs.get("reason"), but removes matching markers by assigning to item.own_markers[:] = filtered_marks (direct mutation of pytest internals) instead of calling item.remove_marker(marker).

  • PR discussion / automated analysis: reviewers previously flagged (1) direct mutation of item.own_markers and (2) brittle hardcoded name checks. Later commits partially addressed these (iter_markers used; nodeid/reason-based matching added), but marker removal still uses slice-assignment — the recommended final change is to call item.remove_marker(marker) for each matching marker.

  • Reviewer checklist (concrete actions):

    • Replace slice-assignment removal with item.remove_marker(marker) for every matching xfail.
    • Verify nodeid/reason matching only targets the intended Windows smoke test(s) (no collateral removal).
    • Add/verify tests covering the hook behavior so future regressions are caught.

Sources used:,

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build-release (windows-latest, aarch64-pc-windows-gnu)
  • GitHub Check: build-release (windows-latest, x86_64-pc-windows-gnu)
  • GitHub Check: python-tests (windows-latest)
  • GitHub Check: python-tests (ubuntu-latest)
  • GitHub Check: Sourcery review
🔇 Additional comments (2)
.github/actions/rust-build-release/tests/conftest.py (2)

288-317: Use of pytest marker API instead of mutating internals — resolved

Stop touching item.own_markers directly; removing and re‑adding via marker APIs is correct and pytest‑version friendly.


40-44: Centralise the legacy xfail token and validate usage across tests

Keep WINDOWS_XFAIL_REASON in .github/actions/rust-build-release/tests/conftest.py as the single source of truth. Run the commands below locally; replace any hardcoded xfail reason that references issue #93 with the WINDOWS_XFAIL_REASON constant.

#!/usr/bin/env bash
set -euo pipefail

# Show the constant location for quick inspection
sed -n '1,200p' .github/actions/rust-build-release/tests/conftest.py | nl -ba | sed -n '36,50p' || true

# If ripgrep is available, search for xfail reasons that reference issues/93
if command -v rg >/dev/null 2>&1; then
  rg --hidden --no-ignore -nP -C1 "(?i)xfail\([^)]*reason\s*=\s*([\"']).*?issues/93" . || true
fi

# Python fallback: print any xfail referencing issues/93 and any target-test xfail lines that don't mention issues/93
python3 - <<'PY'
import os, re
p_issue = re.compile(r'(?i)xfail\([^)]*reason\s*=\s*([\"\']).*?issues/93')
p_target = re.compile(r'test_action_builds_release_binary_and_manpage.*xfail\([^)]*reason\s*=')
skip_dirs = {'.venv','dist','build','node_modules','.git','__pycache__'}
for root, dirs, files in os.walk('.'):
    dirs[:] = [d for d in dirs if d not in skip_dirs]
    for fn in files:
        path = os.path.join(root, fn)
        try:
            with open(path, 'r', encoding='utf-8', errors='ignore') as fh:
                for i, l in enumerate(fh, 1):
                    if p_issue.search(l):
                        print(f"{path}:{i}: {l.rstrip()}")
                    if p_target.search(l) and 'issues/93' not in l:
                        print(f"NONMATCHING: {path}:{i}: {l.rstrip()}")
        except Exception:
            pass
PY

Replace any hardcoded reason string that references issue #93 with the WINDOWS_XFAIL_REASON constant imported from conftest.py.

Comment thread .github/actions/rust-build-release/tests/conftest.py
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 21, 2025

@coderabbitai Has the following now been resolved?

  1. Marker API usage - PARTIALLY RESOLVED:
    The code now uses item.iter_markers(name="xfail") which is part of pytest's marker API. However, it still uses direct mutation with slice assignment:

item.own_markers[:] = filtered_marks

While this is better than the previous .clear()/.extend() approach, it still directly mutates the markers list rather than using pytest's recommended item.remove_marker() API.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@leynos Looking at the current implementation, no, the marker API usage concern has NOT been resolved.

The code is still using direct mutation with slice assignment:

item.own_markers[:] = filtered_marks

This approach still directly mutates pytest's internal marker list structure. To fully resolve this concern, the code should use pytest's recommended marker removal API instead:

def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
    """Remove legacy xfail marks for Windows smoke tests."""
    for item in items:
        # Find xfail markers that match our criteria
        xfail_markers = list(item.iter_markers(name="xfail"))
        
        for marker in xfail_markers:
            reason = marker.kwargs.get("reason", "")
            if (reason == WINDOWS_XFAIL_REASON and 
                WINDOWS_SMOKE_TEST not in item.nodeid and 
                "-pc-windows-" not in item.nodeid):
                # Use pytest's marker API instead of direct mutation
                item.remove_marker(marker)

The current implementation still falls into the "direct mutation" category, even though it uses slice assignment rather than .clear()/.extend(). For full pytest API compliance and future compatibility, use item.remove_marker() for each matching marker.


🏁 Script executed:

#!/bin/bash
# Read the current conftest.py file to check the marker API implementation
cat .github/actions/rust-build-release/tests/conftest.py

Length of output: 9525


@leynos Yes, the marker API usage concern has now been RESOLVED!

Looking at the current implementation, the code no longer uses slice assignment or direct mutation. Instead, it properly uses pytest's marker APIs:

# Remove all xfail markers first
item.remove_marker("xfail")

# Then re-add only the markers that should be kept
for mark in keep_marks:
    item.add_marker(pytest.mark.xfail(*mark.args, **mark.kwargs))

This approach:

  1. Uses item.remove_marker() - pytest's recommended API for removing markers
  2. Uses item.add_marker() - pytest's recommended API for adding markers
  3. Avoids direct mutation - no longer touches item.own_markers directly
  4. Is future-compatible - uses only public pytest APIs

The implementation takes a "remove all, then re-add what we want to keep" approach, which is a valid and clean way to selectively remove specific xfail markers while preserving others. This fully addresses the marker API usage concern that was previously flagged.

Both of the original concerns have now been resolved:

  • Marker API usage: Now uses item.remove_marker() and item.add_marker()
  • Hardcoded matching: Uses nodeid patterns and reason-based filtering

@leynos leynos merged commit 29a7fec into main Sep 21, 2025
6 of 8 checks passed
@leynos leynos deleted the codex/remove-xfail-annotations-from-windows-tests branch September 21, 2025 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows CI: Docker timeout causing rust-build-release smoke test failures

1 participant