Skip to content

Conversation

@EdDev
Copy link
Contributor

@EdDev EdDev commented Oct 26, 2025

What this PR does / why we need it:

In some scenarios, tests are looking for a specific reason or message to be included in the condition.

Although not a formal strict API, the message text includes extended reasoning which is useful for a user operator.
Therefore, it is also included but with an inclusion check.

See usage at:
https://github.com/RedHatQE/openshift-virtualization-tests/blob/0116f056176dbb25da5e8846537264dccb8ef202/tests/network/general/test_bridge_marker.py#L130

Which issue(s) this PR fixes:
Special notes for reviewer:
Bug:

Summary by CodeRabbit

  • New Features
    • Enhanced resource condition checks with optional reason and message filters for more precise validation.
    • Checks now wait for the resource to be available before evaluating conditions.
    • Matching requires the condition status, optional reason, and that the condition message contains the provided substring.
    • Improved error behavior when the expected condition or message isn’t found.

@coderabbitai
Copy link

coderabbitai bot commented Oct 26, 2025

Walkthrough

The Resource.wait_for_condition method now accepts optional reason and message parameters, waits for the resource via self.wait before evaluating conditions, and matches conditions by type, status, optional reason, and by requiring the condition message to contain the provided substring.

Changes

Cohort / File(s) Summary
Resource condition matching API
ocp_resources/resource.py
Extended wait_for_condition signature to `(..., reason: str

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check callers for backward compatibility and updated argument usage.
  • Verify self.wait behavior and timeout/error propagation.
  • Validate condition matching: optional reason handling and substring message check.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: extending the wait_for_condition method with new criteria parameters (reason and message).
Description check ✅ Passed The description addresses the key sections with rationale and usage examples, though some template sections remain empty.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@redhat-qe-bot
Copy link
Contributor

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
  • Pre-commit Checks: pre-commit runs automatically if .pre-commit-config.yaml exists
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified

📋 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

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and 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 python-module-install - Test Python package installation
  • /retest conventional-title - Validate commit message format
  • /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 0 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No WIP, hold, or conflict labels
  5. Verified: PR must be marked as verified (if verification is enabled)

📊 Review Process

Approvers and Reviewers

Approvers:

  • myakove
  • rnetser

Reviewers:

  • dbasunag
  • myakove
  • rnetser
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is automatically removed on each new commit
  • 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.

Copy link

@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

🧹 Nitpick comments (1)
ocp_resources/resource.py (1)

1225-1242: Clarify docstring for optional parameters.

The docstring should explicitly state:

  • That reason and message are optional filters
  • That message performs a substring match (not exact match)
  • The behavior when these parameters are empty strings (i.e., they are ignored)

Apply this diff to improve the docstring:

     def wait_for_condition(
         self, condition: str, status: str, timeout: int = 300, sleep_time: int = 1, reason: str = "", message: str = ""
     ) -> None:
         """
         Wait for Resource condition to be in desire status.
 
         Args:
             condition (str): Condition to query.
             status (str): Expected condition status.
-            reason (str): Expected condition reason.
-            message (str): Expected condition text inclusion.
+            reason (str, optional): Expected condition reason. If empty (default), reason is not checked.
+            message (str, optional): Substring to find in condition message. If empty (default), message is not checked.
             timeout (int): Time to wait for the resource.
             sleep_time(int): Interval between each retry when checking the resource's condition.
 
         Raises:
             TimeoutExpiredError: If Resource condition in not in desire status.
         """
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bac9ea and d638ead.

📒 Files selected for processing (1)
  • ocp_resources/resource.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ocp_resources/resource.py (3)
ocp_resources/node_network_configuration_policy.py (1)
  • status (364-367)
ocp_resources/datavolume.py (1)
  • wait (250-258)
ocp_resources/virtual_machine_import.py (1)
  • wait (194-231)
🔇 Additional comments (1)
ocp_resources/resource.py (1)

1244-1250: Verify timeout allocation between existence check and condition verification.

The current implementation calls self.wait(timeout=timeout) with the full timeout value, then uses timeout_watcher.remaining_time() for condition checking. If the resource takes most of the timeout to exist, there may be insufficient time remaining to verify the condition, leading to premature timeout.

Consider whether the timeout should be split between the existence check and condition verification, or if this behavior is intentional. For better timeout management, you might want:

self.wait(timeout=timeout_watcher.remaining_time(), sleep=sleep_time)

However, this would require careful handling since remaining_time() is called before self.wait(), which is fine. The current code should work correctly - my apologies for the confusion. The self.wait() is called with the user-provided timeout, and then the condition checking uses whatever time remains from the original timeout window.

Copy link

@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

🧹 Nitpick comments (2)
ocp_resources/resource.py (2)

1238-1244: Clarify param semantics and fix minor grammar in the docstring.

Document that reason/message are optional and that message is a substring check. Also fix “desire(d)” wording.

-        Wait for Resource condition to be in desire status.
+        Wait for Resource condition to be in desired status.
@@
-            reason (None): Expected condition reason.
-            message (str): Expected condition text inclusion.
+            reason (str | None): Optional exact condition reason to match. If None, ignored.
+            message (str): Optional substring required to be included in the condition message. If empty, ignored.
@@
-            TimeoutExpiredError: If Resource condition in not in desire status.
+            TimeoutExpiredError: If Resource condition is not in the desired status.

1248-1251: Include reason/message in the log context.

Helps with triage when timeouts occur.

-        self.logger.info(f"Wait for {self.kind}/{self.name}'s '{condition}' condition to be '{status}'")
+        details = []
+        if reason is not None:
+            details.append(f"reason={reason}")
+        if message:
+            details.append(f"message~={message!r}")
+        suffix = f" ({', '.join(details)})" if details else ""
+        self.logger.info(f"Wait for {self.kind}/{self.name} condition '{condition}' == '{status}'{suffix}")
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d638ead and 8264500.

📒 Files selected for processing (1)
  • ocp_resources/resource.py (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-06T08:02:12.098Z
Learnt from: sbahar619
PR: RedHatQE/openshift-python-wrapper#2139
File: ocp_resources/resource.py:256-257
Timestamp: 2024-10-06T08:02:12.098Z
Learning: Constants added to `Condition.Reason` in `ocp_resources/resource.py` may be intended for future use even if currently unused.

Applied to files:

  • ocp_resources/resource.py
🧬 Code graph analysis (1)
ocp_resources/resource.py (2)
ocp_resources/node_network_configuration_policy.py (1)
  • status (364-367)
ocp_resources/virtual_machine_import.py (1)
  • wait (194-231)

@EdDev EdDev changed the title ocp_resources, resource: Extend 'wait_for_condition' criteria fix: ocp_resources, resource: Extend 'wait_for_condition' criteria Oct 28, 2025
@rnetser
Copy link
Collaborator

rnetser commented Oct 29, 2025

/approve
/lgtm

@myakove
Copy link
Collaborator

myakove commented Nov 4, 2025

@EdDev can you please rebase and verity? I want to merge this.

In some scenarios, tests are looking for a specific reason or message to
be included in the condition.

Although not a formal strict API, the message text includes extended
reasoning which is useful for a user operator.
Therefore, it is also included but with an inclusion check.

See usage at:
https://github.com/RedHatQE/openshift-virtualization-tests/blob/0116f056176dbb25da5e8846537264dccb8ef202/tests/network/general/test_bridge_marker.py#L130

Signed-off-by: Edward Haas <[email protected]>
@EdDev
Copy link
Contributor Author

EdDev commented Nov 6, 2025

change: Rebase

@redhat-qe-bot redhat-qe-bot requested a review from rnetser November 6, 2025 08:25
Copy link

@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: 0

🧹 Nitpick comments (1)
ocp_resources/resource.py (1)

1240-1241: Consider clarifying optional parameter behavior in docstring.

While the current docstring is accurate, it could be more explicit about how the optional parameters work:

  • reason (None) → currently doesn't clarify that None means "match any reason"
  • message (str) → doesn't clarify that empty string means "ignore message content"

Consider this enhancement:

         Args:
             condition (str): Condition to query.
             status (str): Expected condition status.
-            reason (None): Expected condition reason.
-            message (str): Expected condition text inclusion.
+            reason (str | None): Expected condition reason. If None (default), any reason matches.
+            message (str): Expected substring in condition message. If empty (default), message is not checked.
             timeout (int): Time to wait for the resource.
             sleep_time(int): Interval between each retry when checking the resource's condition.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8264500 and 1d71613.

📒 Files selected for processing (1)
  • ocp_resources/resource.py (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: sbahar619
Repo: RedHatQE/openshift-python-wrapper PR: 2139
File: ocp_resources/resource.py:256-257
Timestamp: 2024-10-06T08:02:12.098Z
Learning: Constants added to `Condition.Reason` in `ocp_resources/resource.py` may be intended for future use even if currently unused.
Learnt from: sbahar619
Repo: RedHatQE/openshift-python-wrapper PR: 2139
File: ocp_resources/resource.py:256-257
Timestamp: 2024-10-08T23:43:22.342Z
Learning: Constants added to `Condition.Reason` in `ocp_resources/resource.py` may be intended for future use even if currently unused.
📚 Learning: 2024-10-06T08:02:12.098Z
Learnt from: sbahar619
Repo: RedHatQE/openshift-python-wrapper PR: 2139
File: ocp_resources/resource.py:256-257
Timestamp: 2024-10-06T08:02:12.098Z
Learning: Constants added to `Condition.Reason` in `ocp_resources/resource.py` may be intended for future use even if currently unused.

Applied to files:

  • ocp_resources/resource.py
📚 Learning: 2025-10-26T09:13:35.131Z
Learnt from: EdDev
Repo: RedHatQE/openshift-python-wrapper PR: 2544
File: ocp_resources/resource.py:1258-1266
Timestamp: 2025-10-26T09:13:35.131Z
Learning: In ocp_resources/resource.py, EdDev prefers to avoid `continue` statements in loops, favoring single exit points and simple "if-condition-action" structures over early loop skip patterns for better readability and code tracking.

Applied to files:

  • ocp_resources/resource.py
🧬 Code graph analysis (1)
ocp_resources/resource.py (2)
ocp_resources/node_network_configuration_policy.py (1)
  • status (364-367)
ocp_resources/virtual_machine_import.py (1)
  • wait (194-231)
🔇 Additional comments (3)
ocp_resources/resource.py (3)

1225-1233: LGTM! Signature changes are well-designed.

The new optional parameters are correctly typed and defaulted:

  • reason: str | None = None properly distinguishes "not specified" from an empty string value
  • message: str = "" makes the message substring check optional (empty string matches any string)

The signature maintains backward compatibility while enabling the extended condition matching criteria.


1251-1251: Good improvement: waiting for resource before checking conditions.

The addition of self.wait() before condition polling is a sensible enhancement:

  • Ensures the resource exists before attempting to evaluate its conditions
  • Uses TimeoutWatch to track remaining time for the subsequent condition checks (line 1253)
  • Provides clearer separation of concerns (existence vs. condition state)

This is a behavior change from the previous implementation but represents better design.


1258-1266: LGTM! Condition matching logic is correct and clean.

The implementation properly handles optional reason and message parameters:

Reason handling (lines 1261-1263):

  • When reason is None (default): reason field is not added to either dict, so the comparison ignores reason entirely ✓
  • When reason is provided: both dicts include the reason field, requiring an exact match ✓
  • cond.get("reason", "") safely handles conditions without a reason field

Message handling (line 1265):

  • When message = "" (default): the substring check always passes (empty string is in any string), making it optional ✓
  • When message is provided: requires the message to contain the substring ✓
  • cond.get("message", "") safely handles the optional message field

The dictionary comparison approach is elegant and respects your preference for avoiding continue statements while maintaining clear, readable logic.

Based on learnings

@servolkov
Copy link
Contributor

/verified

with RedHatQE/openshift-virtualization-tests#2535

$ uv run pytest --cluster-sanity-skip-nodes-check --cluster-sanity-skip-storage-check --skip-deprecated-api-test --cluster-sanity-skip-check tests/network/general/test_bridge_marker.py
...
collected 4 items / 1 deselected / 3 selected
...
3 of 3 completed, 3 Pass, 0 Fail, 0 Skip, 0 XPass, 0 XFail, 0 Error, 0 ReRun

@rnetser
Copy link
Collaborator

rnetser commented Nov 10, 2025

/approve
/lgtm

@rnetser rnetser merged commit fdf878f into RedHatQE:main Nov 10, 2025
7 checks passed
rnetser pushed a commit to RedHatQE/openshift-virtualization-tests that referenced this pull request Nov 13, 2025
…2535)

##### What this PR does / why we need it:

Use the existing 'wait_for_condition' to query for a specific condition.
Drop local implementation of condition parsing.

* Depends on enhanced 'wait_for_condition' method from the wrapper, in
which the 'reason' and 'message' arguments are available.

##### Which issue(s) this PR fixes:

##### Special notes for reviewer:
Depends on:
RedHatQE/openshift-python-wrapper#2544

##### jira-ticket:
<!-- full-ticket-url needs to be provided. This would add a link to the
pull request to the jira and close it when the pull request is merged
If the task is not tracked by a Jira ticket, just write "NONE".
-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Updated bridge marker tests to replace a dedicated helper with direct
condition checks and an explicit short timeout, improving reliability
and clarity when asserting scheduling failures due to insufficient
bridge resources.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Edward Haas <[email protected]>
jdao-rh pushed a commit to jdao-rh/openshift-virtualization-tests that referenced this pull request Nov 17, 2025
…edHatQE#2535)

##### What this PR does / why we need it:

Use the existing 'wait_for_condition' to query for a specific condition.
Drop local implementation of condition parsing.

* Depends on enhanced 'wait_for_condition' method from the wrapper, in
which the 'reason' and 'message' arguments are available.

##### Which issue(s) this PR fixes:

##### Special notes for reviewer:
Depends on:
RedHatQE/openshift-python-wrapper#2544

##### jira-ticket:
<!-- full-ticket-url needs to be provided. This would add a link to the
pull request to the jira and close it when the pull request is merged
If the task is not tracked by a Jira ticket, just write "NONE".
-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Updated bridge marker tests to replace a dedicated helper with direct
condition checks and an explicit short timeout, improving reliability
and clarity when asserting scheduling failures due to insufficient
bridge resources.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Edward Haas <[email protected]>
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.

6 participants