Skip to content

fix: move multiprocessing_start_method_fork fixture to shared conftest#4808

Merged
rnetser merged 1 commit into
RedHatQE:mainfrom
carterpewpew:fix/move-multiprocessing-fork-fixture-to-shared-conftest
Jun 16, 2026
Merged

fix: move multiprocessing_start_method_fork fixture to shared conftest#4808
rnetser merged 1 commit into
RedHatQE:mainfrom
carterpewpew:fix/move-multiprocessing-fork-fixture-to-shared-conftest

Conversation

@carterpewpew

@carterpewpew carterpewpew commented May 11, 2026

Copy link
Copy Markdown
Contributor
Short description:

Move multiprocessing_start_method_fork fixture to shared conftest for reuse across test directories

More details:

Python 3.14 changed the default multiprocessing start method from fork to forkserver, requiring all Process arguments to be picklable. test_successful_concurrent_uploads passes unprivileged_client to child processes, which contains unpicklable thread locks, causing PicklingError.

What this PR does / why we need it:
  • Moves multiprocessing_start_method_fork fixture from tests/chaos/conftest.py to tests/conftest.py
  • Applies it to test_successful_concurrent_uploads via usefixtures
  • Existing chaos test consumers are unaffected (fixture resolves from parent conftest)
Which issue(s) this PR fixes:

Fixes PicklingError in test_successful_concurrent_uploads on Python 3.14+

Special notes for reviewer:

The multiprocessing import in tests/chaos/conftest.py is kept — it is still used by chaos_worker_background_process.

jira-ticket:

NONE

Summary by CodeRabbit

  • Tests
    • Centralized multiprocessing start-method configuration in the shared test setup.
    • Removed the duplicate fork-mocking fixture from chaos test setup.
    • Updated concurrent upload tests to explicitly use the fork-based start method for more consistent, reliable results.

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Moves the multiprocessing_start_method_fork fixture from tests/chaos/conftest.py into the root tests/conftest.py, applies it to test_successful_concurrent_uploads via @pytest.mark.usefixtures, and deletes the original chaos-scoped fixture.

Changes

Fixture consolidation and application

Layer / File(s) Summary
Fixture centralization in root conftest
tests/conftest.py
Adds multiprocessing import and defines module-scoped multiprocessing_start_method_fork fixture that captures the current start method, forces "fork" using set_start_method(..., force=True), and restores the original method on teardown.
Fixture application to concurrent upload test
tests/storage/cdi_upload/test_upload.py
Applies @pytest.mark.usefixtures("multiprocessing_start_method_fork") decorator to test_successful_concurrent_uploads to ensure it runs with fork-based multiprocessing start method.
Fixture removal from chaos conftest
tests/chaos/conftest.py
Removes the duplicate multiprocessing_start_method_fork fixture previously defined in the chaos-specific conftest.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: moving a pytest fixture to a shared location for reuse.
Description check ✅ Passed The description covers all required sections with sufficient detail: rationale (Python 3.14 multiprocessing changes), solution details (fixture relocation and application), issue reference, and reviewer notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stp Link Required ✅ Passed PR adds fixture (not test function) to tests/conftest.py and modifies existing test_successful_concurrent_uploads. No new test files or test functions added, so STP link requirement doesn't apply.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Linked repositories: Your configuration references 1 linked repositories, but your current plan allows 0. Analyzed ``, skipped RedHatQE/openshift-virtualization-tests-design-docs.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@openshift-virtualization-qe-bot-4

Copy link
Copy Markdown

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: A tracking issue is created for this PR and will be closed when the PR is merged or closed
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: Enabled categories: branch, can-be-merged, cherry-pick, has-conflicts, hold, needs-rebase, size, verified, wip

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest verify-bugs-are-open - verify-bugs-are-open
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. LGTM Count: Minimum 2 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  5. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • dshchedr
  • jpeimer
  • myakove
  • rnetser
  • vsibirsk

Reviewers:

  • Ahmad-Hafe
  • RoniKishner
  • acinko-rh
  • dalia-frank
  • dshchedr
  • ema-aka-young
  • josemacassan
  • jpeimer
  • kgoldbla
  • kshvaika
  • rnetser
  • sarahbx
  • vsibirsk
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
AI Features
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/conftest.py`:
- Around line 231-239: The fixture multiprocessing_start_method_fork currently
sets a process-global start method with scope="module", which can leak side
effects across tests; change its scope to "function" so each test invoking
multiprocessing_start_method_fork uses and restores the start method
independently, and keep the existing behavior of capturing original_start_method
via multiprocessing.get_start_method() and restoring it with
multiprocessing.set_start_method(original_start_method, force=True) in the
teardown to ensure no global state persists.
- Around line 232-239: Add a Google-style docstring to the
multiprocessing_start_method_fork fixture that documents its side effects and
lifecycle: state that it temporarily sets multiprocessing start method to "fork"
to avoid pickling issues, note that it yields control for the test and then
restores the original start method on teardown, and mention any important
caveats (global mutation of multiprocessing behavior and thread-safety
implications). Place this docstring immediately above the
multiprocessing_start_method_fork function definition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 21d85561-e179-4dc0-86d0-6383ec119d8f

📥 Commits

Reviewing files that changed from the base of the PR and between 959c29b and b4b9340.

📒 Files selected for processing (3)
  • tests/chaos/conftest.py
  • tests/conftest.py
  • tests/storage/cdi_upload/test_upload.py
💤 Files with no reviewable changes (1)
  • tests/chaos/conftest.py

Comment thread tests/conftest.py
Comment thread tests/conftest.py

@coderabbitai coderabbitai Bot 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.

♻️ Duplicate comments (1)
tests/conftest.py (1)

231-244: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

CRITICAL: Narrow fixture scope to avoid cross-test global state leakage (unresolved).

This fixture mutates process-global multiprocessing configuration with scope="module", causing all tests in the same module to silently inherit fork mode—even tests that don't request it. Change to scope="function" to constrain the side effect to only the test marked with @pytest.mark.usefixtures("multiprocessing_start_method_fork").

🔧 Proposed fix
-@pytest.fixture(scope="module")
+@pytest.fixture(scope="function")
 def multiprocessing_start_method_fork():

As per coding guidelines: "NEVER use broader scope if fixture modifies state or creates per-test resources" and "No hidden side effects in functions. Function behavior MUST be controlled via explicit arguments, not hardcoded internally."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/conftest.py` around lines 231 - 244, The fixture
multiprocessing_start_method_fork currently sets a process-global
multiprocessing start method with scope="module", causing cross-test leakage;
change its pytest fixture scope to "function" so the side effect is limited to
the individual test that uses
`@pytest.mark.usefixtures`("multiprocessing_start_method_fork"), and ensure the
teardown still restores the original_start_method by using
multiprocessing.get_start_method() and multiprocessing.set_start_method(...,
force=True) as currently implemented.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@tests/conftest.py`:
- Around line 231-244: The fixture multiprocessing_start_method_fork currently
sets a process-global multiprocessing start method with scope="module", causing
cross-test leakage; change its pytest fixture scope to "function" so the side
effect is limited to the individual test that uses
`@pytest.mark.usefixtures`("multiprocessing_start_method_fork"), and ensure the
teardown still restores the original_start_method by using
multiprocessing.get_start_method() and multiprocessing.set_start_method(...,
force=True) as currently implemented.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c5532712-085a-4862-8004-fc4f1e4bed39

📥 Commits

Reviewing files that changed from the base of the PR and between b4b9340 and 97ce5e0.

📒 Files selected for processing (3)
  • tests/chaos/conftest.py
  • tests/conftest.py
  • tests/storage/cdi_upload/test_upload.py
💤 Files with no reviewable changes (1)
  • tests/chaos/conftest.py

@carterpewpew

carterpewpew commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

/verified #4808 (comment)

@openshift-virtualization-qe-bot-3

Copy link
Copy Markdown
Contributor

@coderabbitai

Test execution plan request details

CRITICAL: You MUST post an inline review comment on the first changed line of the first file.
The inline comment should contain the full Test Execution Plan (smoke decision, gating decision, and specific affected tests).
Do NOT submit a blocking review event (REQUEST_CHANGES/APPROVE).
Post a single inline PR comment on Files Changed (non-blocking COMMENT flow).

As an expert software testing engineer, analyze all modified files in this PR and create a targeted test execution plan.
You will post an inline review comment with the test execution plan on the first changed file.
If you fail to run or post a comment, retry.

Analysis Requirements:

  1. Examine code changes in each modified file

  2. Identify affected code paths, functions, and classes

  3. Analyze pytest-specific elements: fixtures (scope, dependencies), parametrization, markers, conftest changes

  4. Trace test dependencies through imports, shared utilities, fixture inheritance, fixture teardown, and yield from cleanup in conftest

  5. Detect new tests introduced in the PR

  6. Utilities and libs impact (when utilities/ or libs/ changes):
    You MUST use shell scripts (rg, git diff) to trace the full impact.
    Follow these sub-steps in order:

    6a. Identify modified symbols: For each changed file under utilities/ or libs/,
    list every modified function or method.
    Example: git diff HEAD~1 --unified=0 -- utilities/hco.py | grep '^[+-]def '

    6b. Find direct callers: Search tests and conftest for each symbol from 6a.
    Example: rg -l 'get_hco_version' tests/

    6c. Trace fixture teardown and cleanup: Find fixtures that reach
    the modified symbol through yield from or context-manager wrappers.
    Example: rg -l 'yield from.*enable_common_boot|def.*enable_common_boot' tests/

    6d. Trace same-file callers: In each changed file, find other functions
    whose body calls a modified symbol (including code after yield
    in @contextmanager helpers).
    Example: rg 'get_hco_version|enable_common_boot' utilities/hco.py

    6e. Expand transitively: If function A calls modified B, then
    tests/fixtures that call A are affected — even when the test body
    never imports B directly.

    Do NOT limit impact to tests that import the modified symbol only.

  7. Smoke test impact: Intersect the affected set from step 6 with smoke-marked tests.
    Run: rg -l '@pytest.mark.smoke' tests/
    VERIFY the above command returned actual file paths before concluding False.
    Set True if either condition is met:

    • a smoke-marked file appears in the affected set from 6b-6e, OR
    • any conftest.py in the smoke test's parent-directory hierarchy (up to repo root)
      imports or calls a modified utilities/libs symbol — including autouse fixtures
      that depend on modified functions. ALL tests in that directory and below are affected.
      Example check: for each smoke_file, scan dirname(smoke_file)/conftest.py,
      dirname(dirname(smoke_file))/conftest.py, etc. for modified symbol imports
      and autouse fixtures that depend on modified symbols.
  8. Gating test impact: Intersect the affected set from step 6 with gating-marked tests.
    Run: rg -l '@pytest.mark.gating' tests/
    Set True if a gating-marked file also appears in the affected set from 6b-6e.
    Utilities/libs changes often affect gating tests without affecting smoke tests.
    Do NOT stop analysis after concluding Run smoke tests: False.

Output rules:
Do NOT include analysis step numbers (1-8) in your visible output.

Your deliverable:
Your inline informational comment will be based on the following requirements:

Test Execution Plan

  • Run smoke tests: True / False — If True, state the dependency path (test → fixture → changed symbol). True ONLY with a verified path.
  • Run gating tests: True / False — If True, state the dependency path. True if any gating-marked test is in the affected set.
  • Affected tests to run (required when utilities/, libs/, or shared conftest changes — list concrete paths even when smoke is False)

Use these formats:

  • path/to/test_file.py - When the entire test file needs verification
  • path/to/test_file.py::TestClass::test_method - When specific test(s) needed
  • path/to/test_file.py::test_function - When specific test(s) needed
  • -m marker - When a marker covers multiple affected tests (e.g. -m gating only if ALL gating tests in scope need run)
  • Tag each listed test or group with its marker when not obvious, e.g. (gating) or (smoke)

Real test commands (MANDATORY when changes affect session/runtime code):

When the affected code runs at session/collection time (conftest fixtures, pytest plugins,
config hooks, session-scoped setup) or modifies runtime behavior that unit tests mock away,
you MUST include concrete pytest commands the PR author must run on a real cluster
to verify the change works end-to-end. Include:

  • A command for the error/fix path (the scenario the PR fixes)
  • A command for the happy path (regression: the normal case still works)
  • Use lightweight tests (e.g., --collect-only for startup failures,
    a single small test for runtime behavior)
    If the PR only changes test logic (not utilities/libs/conftest), the affected test
    paths themselves serve as the real test commands — no separate section needed.

Example output for a session-startup fix:

**Real tests (cluster required)**
Error path (the fix):
`pytest tests/storage/.../test_foo.py --storage-class-matrix=nonexistent-sc --collect-only`
Expected: ValueError with clear message, not IndexError

Happy path (regression):
`pytest tests/storage/.../test_foo.py --storage-class-matrix=<valid-sc> -k test_bar`
Expected: session starts normally

Guidelines:

  • Include tests affected directly OR via fixture setup/teardown, yield from cleanup, or transitive utility call chains (caller calls modified helper)
  • Use a full file path only if ALL tests in that file require verification
  • Use file path + test name when only specific tests use an affected fixture or utility wrapper (preferred for partial file impact)
  • If a test marker can cover multiple files/tests, provide the marker
  • Balance coverage vs over-testing - Keep descriptions minimal
  • Example: if leaf helper foo() changes, include tests whose fixture teardown calls wrapper bar() where bar() calls foo(), even when the test body only imports an unrelated symbol from the same utilities module

Hardware-Related Checks (SR-IOV, GPU, DPDK):

When PR modifies fixtures for hardware-specific resources:

  • Collection Safety: Fixtures MUST have existence checks (return None when hardware unavailable)
  • Test Plan: MUST verify both WITH and WITHOUT hardware:
    • Run affected tests on cluster WITH hardware
    • Verify collection succeeds on cluster WITHOUT hardware

CRITICAL WORKFLOW COMPLETION RULES:

When responding to this test execution plan request, you MUST follow these rules EXACTLY:

  1. YOUR ONLY DELIVERABLE: Post one non-blocking inline comment containing the test execution plan on the first changed line
  2. THEN STOP IMMEDIATELY - Do NOT generate any additional response
  3. FALLBACK ONLY: If inline comment API calls fail after retrying, post as a regular PR comment
  4. SILENCE = SUCCESS: After successfully submitting the review, your task is complete. No confirmation needed.

ABSOLUTE PROHIBITIONS (violating these creates empty/meaningless reviews):

  • ❌ Do NOT post acknowledgment messages like "Test execution plan posted", "Review posted successfully", "I've successfully posted"
  • ❌ Do NOT mention review IDs, URLs, or confirmation of posting in the PR thread
  • ❌ Do NOT add any follow-up comments after submitting the review
  • ❌ Do NOT reply to confirm task completion
  • ❌ Do NOT explain what you did - just do it and stop

Remember: The pull request review is visible to users. Additional comments are redundant noise.

CRITICAL — Verification rules for smoke and gating decisions:
- For each True decision, you must have traced a concrete path: test file → fixture → utility function → modified symbol.
- Do NOT assume impact based on scope, file proximity, or infrastructure-sounding names.
Only set True when you trace a concrete path through steps 6a-6e, then 7 or 8.
WRONG: "utilities/hco.py changed → run smoke" (no traced dependency path)
WRONG: "Run smoke tests: False" with no affected-test list when gating tests use the changed utility
RIGHT: "Run smoke tests: False, Run gating tests: True" plus tests/.../test_foo.py::TestBar::test_baz (gating)
RIGHT: "Smoke test X uses fixture Y → wrapper Z → changed function W in utilities/hco.py"

Comment thread tests/chaos/conftest.py
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all usages of multiprocessing_start_method_fork
rg -n 'multiprocessing_start_method_fork' --type py

echo "---SMOKE---"
rg -l '`@pytest.mark.smoke`' tests/chaos/ tests/storage/cdi_upload/ 2>/dev/null

echo "---GATING---"
rg -l '`@pytest.mark.gating`' tests/chaos/ tests/storage/cdi_upload/ 2>/dev/null

echo "---chaos conftest after change---"
cat tests/chaos/conftest.py 2>/dev/null | head -60

echo "---upload test function---"
rg -n 'test_successful_concurrent_uploads' tests/storage/cdi_upload/test_upload.py -A 10

Length of output: 3348


🏁 Script executed:

#!/bin/bash
# Get PR number and diff to find position of first changed line in tests/chaos/conftest.py
PR_NUMBER=4808
REPO="RedHatQE/openshift-virtualization-tests"

# Get the PR files to find the patch for tests/chaos/conftest.py
gh api repos/${REPO}/pulls/${PR_NUMBER}/files --jq '.[] | select(.filename == "tests/chaos/conftest.py") | {filename: .filename, patch: .patch}'

Length of output: 1210


🏁 Script executed:

#!/bin/bash
PR_NUMBER=4808
REPO="RedHatQE/openshift-virtualization-tests"

BODY="## Test Execution Plan

**Run smoke tests: False**
No smoke-marked test in \`tests/chaos/\` or \`tests/storage/cdi_upload/\` uses \`multiprocessing_start_method_fork\`. The only smoke-marked file in the affected directories is \`tests/storage/cdi_upload/test_upload_virtctl.py\`, which has no dependency on this fixture.

**Run gating tests: False**
Same reasoning — \`test_upload_virtctl.py\` (gating-marked) has no dependency path through \`multiprocessing_start_method_fork\`.

**Affected tests to run**

| Test | Reason |
|---|---|
| \`tests/storage/cdi_upload/test_upload.py::test_successful_concurrent_uploads\` | New direct consumer via \`@pytest.mark.usefixtures\`; this is the PicklingError fix path |
| \`tests/chaos/standard/test_standard.py\` | Fixture previously resolved from \`tests/chaos/conftest.py\`; now resolves from \`tests/conftest.py\` |
| \`tests/chaos/snapshot/test_snapshot.py\` | Same as above |
| \`tests/chaos/migration/test_migration.py\` | Same as above |

**Real tests (cluster required)**

Error path (the fix — PicklingError regression on Python 3.14+):
\`\`\`
pytest tests/storage/cdi_upload/test_upload.py::test_successful_concurrent_uploads
\`\`\`
Expected: test passes without \`PicklingError\`; fork start method is active when \`multiprocessing.Process\` is spawned.

Happy path (regression — chaos tests still resolve the fixture):
\`\`\`
pytest tests/chaos/standard/test_standard.py tests/chaos/snapshot/test_snapshot.py tests/chaos/migration/test_migration.py --collect-only
\`\`\`
Expected: collection completes without \`fixture 'multiprocessing_start_method_fork' not found\` errors."

gh api repos/${REPO}/pulls/${PR_NUMBER}/reviews \
  --method POST \
  -f commit_id="$(gh api repos/${REPO}/pulls/${PR_NUMBER} --jq '.head.sha')" \
  -f body="" \
  -f event="COMMENT" \
  -f "comments[][path]=tests/chaos/conftest.py" \
  -F "comments[][position]=5" \
  -f "comments[][body]=${BODY}"

Length of output: 3797



@carterpewpew

Copy link
Copy Markdown
Contributor Author

/retest tox

@openshift-virtualization-qe-bot

Copy link
Copy Markdown

carterpewpew is not allowed to run retest commands.
maintainers can allow it by comment /add-allowed-user @carterpewpew
Maintainers:

  • jkandasa
  • Aftermath
  • Lorquas
  • mshriver
  • openshift-virtualization-polarion-bot
  • etirta
  • redhat-qe-bot1
  • myakove
  • thrix
  • dajohnso
  • dshchedr
  • dbasunag
  • openshift-virtualization-qe-bot-5
  • openshift-virtualization-qe-bot-3
  • ogajduse
  • redhat-qe-bot2
  • FilipB
  • jsamato
  • RonnyPfannschmidt
  • psav
  • openshift-virtualization-qe-bot-4
  • openshift-virtualization-qe-bot-2
  • jpeimer
  • openshift-virtualization-qe-bot-6
  • vsibirsk
  • EdDev
  • spoore1
  • rnetser
  • openshift-virtualization-qe-bot
  • rlandy
  • quality-innovators-bot
  • omaciel
  • redhat-qe-bot
  • smallamp
  • bsquizz

@openshift-virtualization-qe-bot

Copy link
Copy Markdown

Clean rebase detected — no code changes compared to previous head (fe70b82).
The following labels were preserved: verified, commented-coderabbitai[bot], commented-openshift-virtualization-qe-bot-3, commented-carterpewpew.

@jpeimer

jpeimer commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@carterpewpew please add more information about how it was verified - for example, a pytest command you ran.

@rnetser

rnetser commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

/lgtm

@carterpewpew waiting on your input in #4808 (comment) to approve

@carterpewpew

Copy link
Copy Markdown
Contributor Author

Command run (same for both before/after):

pytest tests/storage/cdi_upload/test_upload.py \
  -k "test_successful_concurrent_uploads" \
  --tc-file=tests/global_config_s390x.py \
  --storage-class-matrix=ocs-storagecluster-ceph-rbd-virtualization \
  -o tmp_path_retention_policy=none

Before (without this PR) — test crashes immediately:

.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/multiprocessing/popen_forkserver.py:47: in _launch
    reduction.dump(process_obj, buf)
.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/multiprocessing/reduction.py:60: in dump
    ForkingPickler(file, protocol).dump(obj)
.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/socket.py:278: in __getstate__
    raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
E   TypeError: cannot pickle 'SSLSocket' object
E   when serializing urllib3.connection.HTTPSConnection state

The forkserver start method (Python 3.14 default) tries to pickle the Kubernetes client's connection pool. Workers never start, test hangs.

After (with this PR) — multiprocessing fork works, test logic executes:

tests/storage/cdi_upload/test_upload.py: 106 warnings
  /home/jathu/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/multiprocessing/popen_fork.py:70:
  DeprecationWarning: This process (pid=1637269) is multi-threaded, use of fork() may lead to deadlocks in the child.
    self.pid = os.fork()

@rnetser @jpeimer

On Python 3.14, the default multiprocessing start method changed from
fork to forkserver (python/cpython#132898), which requires all Process
arguments to be picklable. The unprivileged_client Kubernetes client
object contains thread locks and closures that cannot be pickled,
causing _pickle.PicklingError in test_successful_concurrent_uploads.

Move the multiprocessing_start_method_fork fixture from
tests/chaos/conftest.py to tests/conftest.py so it can be reused
across test directories, and apply it to the affected upload test.

Changes:
- Move fixture to tests/conftest.py (shared across all test dirs)
- Remove duplicate from tests/chaos/conftest.py
- Add @pytest.mark.usefixtures("multiprocessing_start_method_fork")
  to test_successful_concurrent_uploads in test_upload.py
- Existing chaos consumers (test_standard, test_snapshot,
  test_migration) resolve the fixture from the parent conftest

Signed-off-by: Jathavedhan M <jathavedhan.m@ibm.com>
@openshift-virtualization-qe-bot-4

Copy link
Copy Markdown

Clean rebase detected — no code changes compared to previous head (3a8f660).
The following labels were preserved: verified, lgtm-jpeimer, lgtm-rnetser, commented-coderabbitai[bot], commented-openshift-virtualization-qe-bot-3, commented-carterpewpew.

@coderabbitai coderabbitai Bot 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.

♻️ Duplicate comments (1)
tests/conftest.py (1)

231-244: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Module-scoped global start-method mutation leaks across tests.

On Line 231, scope="module" keeps the process-global start method as "fork" for the rest of that module once activated, so tests that did not request this fixture can silently run under a different multiprocessing mode. This creates order-dependent behavior.

Proposed fix
-@pytest.fixture(scope="module")
+@pytest.fixture(scope="function")
 def multiprocessing_start_method_fork():
     """Temporarily set multiprocessing start method to ``fork``.

     Side effects:
         Changes the process-global multiprocessing start method to ``fork``
-        for the module lifetime, then restores the previous method on teardown.
+        for the test lifetime, then restores the previous method on teardown.
     """

As per coding guidelines, function behavior should avoid hidden side effects and remain explicit to the caller.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/conftest.py` around lines 231 - 244, The
multiprocessing_start_method_fork fixture uses scope="module", which causes the
fork start method to persist globally across all subsequent tests in that
module, including those that don't explicitly request this fixture. This creates
hidden side effects and order-dependent behavior. Change the fixture scope from
"module" to "function" so that the multiprocessing start method is only modified
for the specific test function that requests the fixture and is properly
restored immediately after that test completes.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@tests/conftest.py`:
- Around line 231-244: The multiprocessing_start_method_fork fixture uses
scope="module", which causes the fork start method to persist globally across
all subsequent tests in that module, including those that don't explicitly
request this fixture. This creates hidden side effects and order-dependent
behavior. Change the fixture scope from "module" to "function" so that the
multiprocessing start method is only modified for the specific test function
that requests the fixture and is properly restored immediately after that test
completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b2f385fd-e02e-43ec-9e55-90532a611ad5

📥 Commits

Reviewing files that changed from the base of the PR and between 3a8f660 and 3baba0c.

📒 Files selected for processing (3)
  • tests/chaos/conftest.py
  • tests/conftest.py
  • tests/storage/cdi_upload/test_upload.py
💤 Files with no reviewable changes (1)
  • tests/chaos/conftest.py

@jpeimer

jpeimer commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

/approve

@rnetser

rnetser commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

/approve

@openshift-virtualization-qe-bot-3

Copy link
Copy Markdown
Contributor

New container for quay.io/openshift-cnv/openshift-virtualization-tests:latest published

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.